Search code examples
python-2.7weak-referencesstrong-referencesrpyc

How to change a weak reference to a strong reference?


i connect to a client with RPyC and call a Service exposed method with a parameter object. I want to take this object from the exposed method and do somethings with it, but this object is weakly-referenced and at the time i want to access its data: I get a ReferenceError that tells me that the object "weakly-referenced object no longer exists"

How can i safe an object with weak-reference from garbage collection? How can i change it to be strong referenced?

server.py (sending messages)

conn = rpyc.connect(ip,port)
bgsrv = rpyc.BgServingThread(conn)
conn.root.my_remote_method(a, b, c)  # a,b,c are integer, strings etc.
time.sleep(0.2)
bgsrv.stop()
conn.close()

client.py (handling data and put it into a queue)

class MessageService(Service):
    def exposed_my_remote_method(self, a, b, c):
        ThreadedClient.queue.put([a,b,c])

other.py (reading the queue)

def read_queue(self):
    """ Handle all the messages currently in the queue (if any) """
    while ThreadedClient.queue.qsize():
        try:
            msg = ThreadedClient.queue.get(0)
            self.read_message(msg)
        except Queue.Empty:
            pass

def read_message(self, msg):
    # do something with the data of a, b, c
    res = msg[0] + xy # ReferenceError

Solution

  • This shouldn't happen with primitives (ints, strings, etc.), but can certainly happen with general objects. What you need to do in the server is to obtain the objects, which creates a copy of them in the server process, no longer depending on the reference to be kept in the client process.

    class MessageService(Service):
        def exposed_my_remote_method(self, a, b, c):
            a,b,c = rpyc.classic.obtain([a,b,c])
            ThreadedClient.queue.put([a,b,c])
    

    This can also be achieved by using deliver in client process.