[Twisted-Python] waitForDeferred Question

Moof moof at metamoof.net
Sat Mar 11 07:37:43 EST 2006


> I am not super familiar with PyShell/PyCrust, but I think everything
> (including the prompt generation) is done asynchronously.  The only
> thing that could really block would be long running python code
> executed in the users namespace in PyShell.  But, I do like the idea
> of having immediate results return directly, but have everything else
> become a background job.  But, the question still remains - how do you
> convert a Deferred() to a blocking, directly returned result?

You could use something like
http://svn.twistedmatrix.com/cvs/sandbox/exarkun/threadwrapper.py?view=markup&rev=12804
but I really dont' reccommend it. I think redefining the way the
interpreter works is the way ahead.

One way to do it would be to think of the space between the last >>>
prompt and the current one as "flexible". How about this for an
example session:

>>> somethingThatReturnsADeferred()

this will return a deferred, so natually the first thing you do is
attach callbacks and errbacks to it to know when the deferred has
finished. You display some indication of this:

<Deferred 1 at 0x12345678. Currently: Running>
>>>

You even make a nice coloured "running" icon to put on one side, if
you want. When it stops, you change "Running" to "Completed", in the
same line. Assuming nothing has been done yet, you either raise the
exception (or, I'd prefer printing out the traceback and putting the
Failure in a special variable, called, say _f, it's more flexible) or
print out repr(d.result) before putting d.result in _ and the deferred
in, say, d. The important thing here is to print out the result in the
space between the two >>>, expanding it as necessary. Thus the screen
ends up looking like this:

>>>  somethingThatReturnsADeferred()
<Deferred 1 at 0x12345678. Currently: Completed>
Result from Deferred 1:
['this', 'is', 'a', 'result']
>>>

If someone has already executed a new command, you display *which*
deferred the result comes form and skip the _ and d assignemnt step,
maybe assiging it to another special variable.

Other enhancement would be to add currently pending deferreds to a
variable or command you can quickly use to check the status, eg:

>>> jobs
1. <Deferred 1 at 0x12345678: Running, Next callback: somefunc(result,
arg1, arg2, kw1=val1>
2. <Deferred 2 at 0x12345679: Running, Next callback: somefunc(result,
arg1, arg2, kw1=val4>
3. <Deferred 3 at 0x12345680: Running, Next callback: somefunc(result,
arg1, arg2, kw1=val3>
>>> important_deferred = jobs[1] #so that deferred will not be garbage
collected once it falls out of scope

You might also want to add a convenience function result() which takes
a deferred and does the whole putting of the result in _ and the
deferred in d.

There are plenty of ways to do it. Trying to make it look blocking is
the wrong way to go about it, IMO.

Also, I'd be quite interested to see a twisted-compatible PyCrust.
Maybe even adding the twisted log to a tab in the bottom pane of the
window. I'd be happy to lend a hand in coding such a beast, if you'd
like one.

It'd be especilly nice if it could do something manhole-compatible, so
pycrust could attach to remote twisted processes...

Moof




More information about the Twisted-Python mailing list