[Twisted-Python] Twisted and ipython

Alessandro Dentella sandro at e-den.it
Mon Jan 17 02:31:21 MST 2011


Thanks Glyph,

On Mon, Jan 17, 2011 at 12:07:42AM -0500, Glyph Lefkowitz wrote:
> > From what you say I don't know if completion is something I'd
> > get with invective of urwid.
> 
> Invective is an IRC client (with a useful text-editing widget for Twisted's "insults" module).  urwid is a client library.  Completion is something that you'd need to implement yourself with either of these (as is a functional Python interpreter...)

ok, clear.

> twisted.protocols.telnet is old and really should not be used.  The new,
> good telnet implementation is in twisted.conch.telnet.  You can find code
> that uses this (both a runnable application and an instructive example) in
> twisted.conch.manhole_tap, which also happens to include a python
> interpreter as its application.

ok, I found demo.tac and demo_manhole.tac and will have a deeper look at them.

> > Twisted in a thread - working setup
> > -----------------------------------
> > 
> > Following a hint in the ipython ml I started a second thread for twisted and
> > I'm using blockingcallFromThread to dispatch commands to the reactor:
> 
> You can do this in pretty much any interactive Python interpreter, including the default one.  It's not very convenient, though :).
> 
> > What I can't understand is why I can't put "q.discover_modules()" inside
> > callWhenRunning() command: if I do that it just blocks at the first
> > iteration of the 'for' loop.

> Because callWhenRunning will schedule start_command to be run on the main
> (reactor) thread.  

mmh.... in my case the reactor thread in not the main one!
IPython.twistedutil.ReactorInThread does that for me

I'm calling it from the main thread, that is not the reactor's thread in my case

    rit = twistedutil.ReactorInThread()
    rit.setDaemon(True)
    rit.start()

> (callWhenRunning may only be called _from_ the main thread, too, which it
> seems like you might not be doing).


> Since start_command is running on the main thread, when it gets around to
> blockingCallFromThread, it puts some work into the queue for the reactor
> to do, then goes to sleep forever, trusting that the main thread will do
> the work and then wake it up.  Except - oops! - it just put the main
> thread to sleep forever, so it will never wake up.
> 
> If you'd like, you can file a ticket for blockingCallFromThread to raise a
> loud, angry exception if it is invoked from the reactor thread.

Ok I think this is the turning key. I imagine that if I start the reactor in
a separate secondary thread, calling reactor.callWhenRunnning(start_command)
from the main thread makes 'start_command' be run in the reactor's
thread. At that point I can't call blockingCallFromThread from that thread,
as you pointed out. If this assumption is wrong, please let me know and I'll
go to study threads.


> (Also, in the simple example you gave, you're invoking
> blockingCallFromThread with the wrong signature; the first argument must
> be a reactor.  The rest of my explanation was based on the assumption that
> this is not the exact code you're running, since that would log a
> traceback immediately.  Or, perhaps the fact that you're calling
> callWhenRunning from a non-main thread is blowing up in some more
> insidious way and that's the real problem.)

Sorry for the confusion. This *is* the correct code but blockingCallFromThread is
really IPython.twsitedutil.blockingCallFromThread that wraps
twisted.internet.threads.blockingCallFromThread passing the reactor as first arg.

thanks again for the valuable explanation

sandro
*:-)


-- 
Sandro Dentella  *:-)
http://www.reteisi.org             Soluzioni libere per le scuole
http://sqlkit.argolinux.org        SQLkit home page - PyGTK/python/sqlalchemy




More information about the Twisted-Python mailing list