[Twisted-Python] how to get an idle callback while running a reactor?

Jean-Paul Calderone exarkun at divmod.com
Sat Dec 20 09:28:07 EST 2008


On Sat, 20 Dec 2008 07:10:53 -0700, Joe Strout <joe at strout.net> wrote:
>I'm trying to make a simple AIM bot that, in addition to responding when I 
>talk to it, can also send me a message on its own initiative.  My code is 
>based on SkippyTalkBot [1], but I confess that I don't understand it very 
>well, and though I've been crawling the Twisted documentation for a few days 
>now, it's still rather mysterious to me.
>
>So I'm at a loss as to how to add an "idle" function that will allow my bot 
>to periodically see whether it has something new to say to the user.

While this sometimes makes sense, it's usually *not* the approach you want
to take.  You're describing a solution which is essentially polling.  And
polling is not as good as responding to events.  You *could* run a function
ten times a second that looks around for a message to send and sends it if
it finds one.  Or, whatever event occurs which creates those messages could
just send the message instead of putting it in a pile and waiting for your
poller to find it.

I can't tell you how to do this in detail, though, since I don't know what
causes you to have messages to send.

> [snip]
>
>Now, from trawling the docs, I guess that I want to call 
>reactor.callWhenRunning...

Probably not.  If you want to run a function later (and that's how polling
is generally implemented), you want reactor.callLater.  If you want to run
a function repeatedly at a fixed interval, twisted.internet.task.LoopingCall
will help.

>but then I'd like to pass in a bound method of my 
>B class, so it can call sendMessage on myself.  But I'm stumped as to how my 
>B class is even being instantiated, let alone how to get a reference to that 
>instance.  And the callWhenRunning idea is only a wild guess and probably 
>wrong.

You'll probably encounter the same problem with reactor.callLater as you
were encountering with reactor.callWhenRunning, though.  How do you get
a reference to the bound method to pass in?  That's simple - don't call
the reactor method until you *have* an instance.  You can call almost any
reactor method even *after* the reactor is started; you do not have to set
everything up before you call reactor.run.

You can read more about reactor.callLater in the scheduling howto:

 http://twistedmatrix.com/projects/core/documentation/howto/time.html

Jean-Paul




More information about the Twisted-Python mailing list