[Twisted-Python] follow up: at what point does reactor.run() need to be called?

Neil Blakey-Milner nbm at mithrandr.moria.org
Wed Apr 7 04:48:55 EDT 2004


On Wed 2004-04-07 (01:04), Damon Fasching wrote:
> 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?

'reactor.run()' (almost) only returns when you're about to exit your
program.

It starts an "event loop", whereby it responds to events (such as
information arriving from sockets, timers expiring, &c.) for the rest of
its existence.

Event-based programming requires you to think about actions as responses
to events that may occur any time in the future relative to where you
are in the code.  So, you might:

1) After the reactor is called, a callLater'd function will be called
that will attempt to connect to a server.

2) An event informs you that you've been connected to that server, and
you send a query to the server.

3) An event informs you that the server has sent you some data (or
you're using LineReceiver, sux, or some other higher-level event
generator), and you close the connection.  Based on the data you
received, you want to connect to another server.

4) An event informs you that you've connected to the new server.  You
send the stored information or something derived from it to the server.

5) An event informs you that the new server has successfully received
your message (say, you're using SMTP and get an appropriate delivery
response).  You close the connection.  You set up a callLater function
to be called in five minutes start at step 1 again.

...

So, "at a later point" is a response based on an event - either
time-based or I/O-based (but probably abstracted away from simple socket
I/O for you).

If you start the reactor before setting up things that will generate
events, the reactor will never receive any events, and as such won't
start the response functions (callbacks), so basically nothing will
happen.

But you can set up new things that generate events (ie, connect to new
servers, start your own server, set up timers) after the reactor starts,
it just has to be in a response to some other event.

Neil
-- 
Neil Blakey-Milner
nbm at mithrandr.moria.org
http://mithrandr.moria.org/




More information about the Twisted-Python mailing list