[Twisted-Python] follow up: at what point does reactor.run() need to be called?
Damon Fasching
damon.fasching at sbcglobal.net
Wed Apr 7 02:04:34 MDT 2004
Hi,
I'm still confused.
Here is the working code, again.
# ================= server.py ====================
from twisted.spread import pb
from twisted.internet import reactor
class ServerClass(pb.Root):
def remote_shutdown(self):
print "server stopping"
reactor.stop()
reactor.listenTCP(8789,
pb.PBServerFactory(ServerClass()))
reactor.run()
# =========== client.py =============
from twisted.spread import pb
from twisted.internet import reactor
def gotRootObject(obj):
d = obj.callRemote("shutdown")
d.addCallback(serverStopped)
d.addErrback(remoteCallFailure)
def serverStopped(result):
print 'server stopped'
stop()
def remoteCallFailure(reason):
print "remote call failed: %s" % (reason.value)
stop()
def stop():
print "client stopping"
reactor.stop()
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
d = factory.getRootObject()
d.addCallback(gotRootObject)
d.addErrback(remoteCallFailure, "getRootObject")
reactor.run()
============
And here is a modification to the last lines of
client.py which breaks it, in this case causes it to
hang. (server does not get the shutdown call and
client is not stopped, so it seems the callback for
getRootObject is not executed.)
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
d = factory.getRootObject()
reactor.run()
d.addCallback(gotRootObject)
d.addErrback(remoteCallFailure, "getRootObject")
==============================================
> It doesn't hang, it just gets the root object, but
> has no callback to pass it to.
Huh? What about the line
d.addCallback(gotRootObject)? It's still there, just
a little further down, and d is still d, the deferred
object returned by getRootObject. Does the call to
reactor.run() change the deferred, d?
What I really see as a limitation is that it seems
that I must connect to all of my servers before
starting the reactor, something which is only done
once per process. And because of that, I can't
interact with any of the servers until I have
connected to all of them (because the reactor isn't
running before then).
For example, why does the client hang if I change the
last lines to the following?
reactor.run()
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
d = factory.getRootObject()
d.addCallback(gotRootObject)
d.addErrback(remoteCallFailure, "getRootObject")
This seems to be an inevitable sequence of calls if I
want to be able to connect to a server after having
already connected to and intereacted with other
servers. Start the reactor, do some stuff, and then
at a later point, connect to another server. If I
substitute those lines for the original last 6 lines,
start the server and start the client...nothing
happens. They both just sit there.
What have I misunderstood?
How can I connect to a server on the fly?
> The value, that getRootObject() returns is a
Deferred
> object. This is a "delayed" function call (which is
> also non-blocking), so the *real* rootObject is
> passed to the Deferred.callback function.
Right, it's the obj argument of the gotRootObject()
method in the original code.
> --
> mp
Thanks,
Damon
More information about the Twisted-Python
mailing list