Question

I'm developing a python program to monitor and control a game-server. The game-server has many game-cores, and those cores handle the clients.

I have a python class called Server that holds instances of the class Core, and those instances are used to manage the actual game-cores. The Core class needs to connect to the game-core via TCP-Socket, in order to send commands to that specific game-core. To close those sockets properly, the Core class has a __del__ method which closes the socket.

An example:

class Server(object):
    Cores = [] # list which will be filled with the Core objects
    def __init__(self):
        # detect the game-cores, create the core objects and append them to self.Cores

class Core(object):
    CoreSocket = None # when the socket gets created, the socket-object will be bound to this variable
    def __init__(self, coreID):
        # initiate the socket connection between the running game-core and this python object

    def __del__(self):
        # properly close the socket connection

Now, when I use the Core class itself, the destructor always gets called properly. But when I use the Server class, the Core objects inside Server.Cores never get destructed. I have read that the gc has a problem with circular references and classes with destructors, but the Core objects never reference the Server object (only the socket-object, in Core.CoreSocket), so no circular references are created.

I usually prefer using the with-statement for resource cleaning, but in this case I need to send commands over many different methods in the Server class, so using with won't help ... I also tried to create and close the socket on each command, but that really kills the performance when I need to send many commands. Weak refereneces created with the weakref module won't help eigther, because the destructors then get called immediately after I create the Server object.

Why don't the Core objects get destructed properly when the Server object gets cleaned up by the gc? I guess I'm just forgetting something simple, but I just can't find out what it is.

Or maybe there is a better approach for closing those sockets when the object gets cleaned up?

Was it helpful?

Solution

You've mixed up class and instance members. Unlike in some other languages, defining a variable at class scope creates a class variable, not an instance variable. When a Server instance dies, the Server class is still around and still holds references to the cores. Define self.cores in the __init__ method instead:

class Server(object):
    def __init__(self):
        self.cores = []
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top