[Twisted-Python] blocking question
Bob Ippolito
bob at redivi.com
Fri Apr 18 10:52:30 MDT 2003
On Thursday, Apr 17, 2003, at 23:43 America/New_York, Andrew Bennetts
wrote:
> On Thu, Apr 17, 2003 at 11:15:06PM -0400, Konrad Rokicki wrote:
>> Hey everyone, newbie question:
>> Are there any Python/Twisted idioms for doing blocking? More
>> specifically,
>> in a client I have a method to send a query to the server and another
>> method that gets called when the query is answered. Is there an easy
>> way
>> to say "send the query then wait x seconds for it to return in this
>> function"?
>> It seems like blocking is taboo in twisted and if anyone has an
>> alternative I'd be glad to hear it. I guess I could do this
>> asynchronically but it would be a pain I think.
>
> See http://twistedmatrix.com/documents/howto/defer for more details on
> using
> Deferreds. See also the "Writing a Server" and "Writing a Client"
> howtos.
> This is pretty basic Twisted stuff, so the existing docs cover it
> pretty
> well.
Is Glyph's Deferred talk from PyCon online yet? That might also be
useful.
krad - You should've just gone to PyCon man, it was right in DC at GWU
and there were god knows how many talks about various pieces of Twisted.
The only time threads are used in Twisted is if an API that only
provides a blocking interface must be used.. for example,
twisted.enterprise uses a threadpool to dispatch queries to DBAPI
compliant databases, since DBAPI is synchronous and blocking. The only
other way around this is to have a pool of worker processes instead of
worker threads, but you don't really have anything to gain with this
approach b/c it uses more memory/resources and IPC is slower than
thread communication.
But yeah, what you want to do is definitely the kind of thing that you
should be using Deferreds for.. Also, due to the chaining behavior, you
can do something practical like this:
from twisted.web import microdom, client
# Start webpage fetch
d = client.getPage('http://example.com/somewebpage.html')
# If webpage fetch takes more than aFewSeconds, raise error
d.setTimeout(aFewSeconds)
# Take the web fetch result, and parse it into a DOM tree
# equivalent to saying: microdom.parseString(webFetchResult,
beExtremelyLenient=1)
d.addCallback(microdom.parseString, beExtremelyLenient=1)
# this will get triggered if the timeout happens, or if there's a parse
error
# however, with beExtremelyLenient, there usually won't be one.. it can
parse some f'ed up html
d.addErrback(yourTimeoutOrParseErrorHandler)
# If everything goes OK, or if for some reason
yourTimeoutOrParseErrorHandler returns a non-Failure result
# call yourPageHandlerThatUnderstandsDOMTrees(result)
# because microdom.parseString was called on the result, it is now a
DOM tree instead of a string
d.addCallback(yourPageHandlerThatUnderstandsDOMTrees)
Another convenient thing about deferreds is that if the result of some
callback is a deferred, then it will automagically be chained as
well... for example, if yourPageHandlerThatUnderstandsDOMTrees wants to
pass a fetched URL to the next callback handler, then all it has to do
is return client.getPage(someURL) and the next handler will receive the
result of that request, not the deferred instance for that request.
-bob
More information about the Twisted-Python
mailing list