[Twisted-Python] Re : executing .rpy in a thread

With the help of your hint I have come up with the following code. For simplicity's sake I don't use .rpys here since it shouldn't change the approach. What happens when I run this code and open the servers root in a webbrowser is that I get a page saying "NOT_DONE_YET." Also when I get rid of the quotation marks in the return statement it does not seem to work. Python just tells me that it does not know NOT_DONE_YET. I am also not coherent in my head of how to pass the request variable to my doLongPageGeneration function. Is it correct how I registered the callbacks? Thanks to all the twisted gurus, _stephan ---------------------------------------------------start from twisted.web import server, resource, static, script from twisted.internet import reactor from twisted.internet import threads def doLongPageGeneration(): return "<html><b>H</b>ello, <b>W</b>orld!</html>" class Simple(resource.Resource): isLeaf = True def render(self, request): d = threads.deferToThread(doLongPageGeneration) d.addCallback(request.write) d.addCallback(request.finish) return "NOT_DONE_YET" site = server.Site(Simple()) reactor.listenTCP(8080, site) reactor.run() ------------------------------------------------------end
The easiest way to run code in a thread and get the result back is with twisted.internet.threads.deferToThread. Your Resource's render method would need to return NOT_DONE_YET, and you'd need to add callbacks to the Deferred from deferToThread that call request.write(...) and request.finish().
Say I want to execute blocking code in a .rpy file. Can't I just execute all the code in a separate thread? I've found the following code to execute a function in a thread. How could I add a callback to that thread so I could get back the whole html page back from that "notthreadSafe" function and return it to the client (web browser)?
-- +++ GMX - die erste Adresse für Mail, Message, More! +++ Getestet von Stiftung Warentest: GMX FreeMail (GUT), GMX ProMail (GUT) (Heft 9/03 - 23 e-mail-Tarife: 6 gut, 12 befriedigend, 5 ausreichend) Jetzt selbst kostenlos testen: http://www.gmx.net

On Tue, 2003-09-16 at 14:38, Jerome Jushima wrote:
class Simple(resource.Resource): isLeaf = True def render(self, request): d = threads.deferToThread(doLongPageGeneration) d.addCallback(request.write) d.addCallback(request.finish) return "NOT_DONE_YET"
Should be: return server.NOT_DONE_YET -- Alex Levy WWW: http://mesozoic.geecs.org "Never let your sense of morals prevent you from doing what is right." -- Salvor Hardin, Isaac Asimov's _Foundation_

On Tue, 16 Sep 2003 20:38:14 +0200 (MEST) "Jerome Jushima" <ccom@gmx.net> wrote:
d.addCallback(request.finish)
Should be d.addCallback(lambda _: request.finish()) since it takes no arguments. However, this approach in general is wrong. Using Woven is probably a better way of dealing with this, since it handles Deferreds transparently. -- Itamar Shtull-Trauring http://itamarst.org/ Available for Python & Twisted consulting

On Tuesday, Sep 16, 2003, at 15:10 America/New_York, Itamar Shtull-Trauring wrote:
On Tue, 16 Sep 2003 20:38:14 +0200 (MEST) "Jerome Jushima" <ccom@gmx.net> wrote:
d.addCallback(request.finish)
Should be d.addCallback(lambda _: request.finish()) since it takes no arguments. However, this approach in general is wrong. Using Woven is probably a better way of dealing with this, since it handles Deferreds transparently.
It's definitely not wrong to go without Woven in a lot of cases, such as non-XML output, but I provided a Pretty Good Example of how to do what he asked in my previous message in this thread. -bob

On Tuesday, September 16, 2003, at 03:10 PM, Itamar Shtull-Trauring wrote:
Should be d.addCallback(lambda _: request.finish()) since it takes no arguments. However, this approach in general is wrong. Using Woven is probably a better way of dealing with this, since it handles Deferreds transparently.
What you *really* want to do is apply the patch I posted earlier that makes render handle deferreds properly, and then do: ---cut--- from twisted.web import server, resource, static, script from twisted.internet import reactor from twisted.internet import threads def doLongPageGeneration(): return "<html><b>H</b>ello, <b>W</b>orld!</html>" class Simple(resource.Resource): isLeaf = True def render(self, request): return threads.deferToThread(doLongPageGeneration) site = server.Site(Simple()) reactor.listenTCP(8080, site) reactor.run() ---cut--- James

On Tuesday, Sep 16, 2003, at 14:38 America/New_York, Jerome Jushima wrote:
With the help of your hint I have come up with the following code. For simplicity's sake I don't use .rpys here since it shouldn't change the approach. What happens when I run this code and open the servers root in a webbrowser is that I get a page saying "NOT_DONE_YET." Also when I get rid of the quotation marks in the return statement it does not seem to work. Python just tells me that it does not know NOT_DONE_YET.
This is how you want to do it, there should be no surprises with this approach (it handles failures, logs to stdout): from twisted.web import server, resource, static, script from twisted.internet import reactor, threads from twisted.python import log import sys def doLongPageGeneration(request): # you *could* inspect the request object if you needed to from here # but I wouldn't *change* it from this thread! return "<html><b>H</b>ello, <b>W</b>orld! - Your user agent is %s</html>" % request.getHeader('user-agent') def writeRequestAndFinish(data, request): request.write(data) request.finish() class Simple(resource.Resource): isLeaf = True def render(self, request): threads.deferToThread(doLongPageGeneration, request).addCallback(writeRequestAndFinish, request).addErrback(request.processingFailed) return server.NOT_DONE_YET site = server.Site(Simple()) reactor.listenTCP(8080, site) # I'm not sure if this is strictly necessary, but it seems like a good idea. reactor.initThreads() log.startLogging(sys.stdout) reactor.run()

How would I create a .tap file to execute the example below? Ray On Tue, 2003-09-16 at 12:20, Bob Ippolito wrote:
On Tuesday, Sep 16, 2003, at 14:38 America/New_York, Jerome Jushima wrote:
With the help of your hint I have come up with the following code. For simplicity's sake I don't use .rpys here since it shouldn't change the approach. What happens when I run this code and open the servers root in a webbrowser is that I get a page saying "NOT_DONE_YET." Also when I get rid of the quotation marks in the return statement it does not seem to work. Python just tells me that it does not know NOT_DONE_YET.
This is how you want to do it, there should be no surprises with this approach (it handles failures, logs to stdout):
from twisted.web import server, resource, static, script from twisted.internet import reactor, threads from twisted.python import log import sys
def doLongPageGeneration(request): # you *could* inspect the request object if you needed to from here # but I wouldn't *change* it from this thread! return "<html><b>H</b>ello, <b>W</b>orld! - Your user agent is %s</html>" % request.getHeader('user-agent')
def writeRequestAndFinish(data, request): request.write(data) request.finish()
class Simple(resource.Resource): isLeaf = True def render(self, request): threads.deferToThread(doLongPageGeneration, request).addCallback(writeRequestAndFinish, request).addErrback(request.processingFailed) return server.NOT_DONE_YET
site = server.Site(Simple()) reactor.listenTCP(8080, site) # I'm not sure if this is strictly necessary, but it seems like a good idea. reactor.initThreads() log.startLogging(sys.stdout) reactor.run()
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

On Wed, Sep 17, 2003 at 05:16:46PM -0700, Ray Price wrote:
How would I create a .tap file to execute the example below?
On Tue, 2003-09-16 at 12:20, Bob Ippolito wrote: [...]
reactor.run()
It calls reactor.run, so you can't use twistd on this file. Just run it directly, it's an ordinary Python script. -Andrew.
participants (7)
-
Alex Levy
-
Andrew Bennetts
-
Bob Ippolito
-
Itamar Shtull-Trauring
-
James Y Knight
-
Jerome Jushima
-
Ray Price