Hi,
I'm running web2.server (much like the example at http://twistedmatrix.com/projects/web2/documentation/examples/intro/simple.p... ) and everything works well, except if I return a deferred from an IResource.render() :
This does NOT work: def render(self, req): #... deferredResponse = h.getResponse() # generates a deferred return deferredResponse While this DOES work: def render(self, req): #... deferredResponse = h.getResponse() # generates a deferred deferredResponse.callback(None) return deferredResponse.result
According to the docs ( http://twistedmatrix.com/projects/web2/documentation/howto/object-traversal.... ) I should
Return an IResponse or a deferred which will fire an IResponse.
What's wrong here? Does anybody have a working exmaple? To where does render() return its result?
My versions:
twisted.__version__
'2.4.0'
twisted.web2.__version__
'0.2.0'
python -V
Python 2.4.4
I hope somebody can help. Thx, ibu
On Thu, 12 Apr 2007 21:35:57 +0200, ibu ibu@radempa.de wrote:
Hi,
I'm running web2.server (much like the example at http://twistedmatrix.com/projects/web2/documentation/examples/intro/simple.p... ) and everything works well, except if I return a deferred from an IResource.render() :
This does NOT work: def render(self, req): #... deferredResponse = h.getResponse() # generates a deferred return deferredResponse
While it may be the case that a program can only work in one particular way (and so saying that a program works may fully describe its behavior), it is not the case that a program can only be broken in one particular way. Don't just say that something doesn't work. Explain the behavior you expected to see and how the behavior you did see differed from that. It's also very useful to include complete examples. In the above, I have no idea what `h' is or what `h.getResponse' might return. This means I really have no idea what the render method might even be trying to do, let alone what it actually does.
While this DOES work: def render(self, req): #... deferredResponse = h.getResponse() # generates a deferred deferredResponse.callback(None) return deferredResponse.result
The `result' attribute of Deferreds is not strictly public, and you should avoid using it. The above is equivalent to returning f(None), where f is the composite function of all of the callbacks on deferredResult, though what those might be I do not know.
Jean-Paul
You are right, I should not say that it is not working; I should say it is not working as I expected, and my expectations regarding deferreds may well be wrong, since I am new to them.
Anyway, here is a full example code, which (when run with twistd -l - -noy ) does render the expected output line correctly. Upon removing the comment the http client does not receive an answer to the http request however.
I'd just like to know how I can correctly return a deferred from render(), or to where render() returns.
Thx, ibu
---------------------------------------------------------------------->>>>>
from twisted.web2 import server, http, resource, channel, http_headers from twisted.internet import defer
class Handler: def __init__(self, request): self.request = request def err(self, e): print "---- errb", e def getResponse(self, result = None): rep = "The output which shall be transferred to the browser." res = http.Response( 200, {'content-type': http_headers.MimeType('text','plain')}, rep) print "---- getResponse returning: ", res return res def getDeferredResponse(self): print "---- getDeferredResponse beginning" d = defer.Deferred() d.addCallback(self.getResponse) d.addErrback(self.err) print "---- getDeferredResponse returning: ", d return d
class Toplevel(resource.Resource): addSlash = True def render(self, r): h = Handler(r) deferredResponse = h.getDeferredResponse() #return deferredResponse deferredResponse.callback(None) return deferredResponse.result
site = server.Site(Toplevel())
from twisted.application import service, strports application = service.Application("demoserver") s = strports.service('tcp:8080', channel.HTTPFactory(site)) s.setServiceParent(application)
<<<<<------------------------------------------------------------------------
----- Original message ----- From: Jean-Paul Calderone (Jean-Paul Calderone exarkun@divmod.com) To: twisted-web@twistedmatrix.com Cc: Date: Thursday 12 April 2007 21:54 (UTC+1) Subject: Re: [Twisted-web] web2.server: returning a deferred from IResource.render()
On Thu, 12 Apr 2007 21:35:57 +0200, ibu ibu@radempa.de wrote:
Hi,
I'm running web2.server (much like the example at http://twistedmatrix.com/projects/web2/documentation/examples/intr o/simple.py ) and everything works well, except if I return a deferred from an IResource.render() :
This does NOT work: def render(self, req): #... deferredResponse = h.getResponse() # generates a deferred return deferredResponse
While it may be the case that a program can only work in one particular way (and so saying that a program works may fully describe its behavior), it is not the case that a program can only be broken in one particular way. Don't just say that something doesn't work. Explain the behavior you expected to see and how the behavior you did see differed from that. It's also very useful to include complete examples. In the above, I have no idea what `h' is or what `h.getResponse' might return. This means I really have no idea what the render method might even be trying to do, let alone what it actually does.
While this DOES work: def render(self, req): #... deferredResponse = h.getResponse() # generates a deferred deferredResponse.callback(None) return deferredResponse.result
The `result' attribute of Deferreds is not strictly public, and you should avoid using it. The above is equivalent to returning f(None), where f is the composite function of all of the callbacks on deferredResult, though what those might be I do not know.
Jean-Paul
Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
On Thu, 12 Apr 2007 15:55:36 -0500, ibu ibu@radempa.de wrote:
from twisted.web2 import server, http, resource, channel, http_headers from twisted.internet import defer class Handler: def __init__(self, request): self.request = request def err(self, e): print "---- errb", e def getResponse(self, result = None): rep = "The output which shall be transferred to the browser." res = http.Response( 200, {'content-type': http_headers.MimeType('text','plain')}, rep) print "---- getResponse returning: ", res return res def getDeferredResponse(self): print "---- getDeferredResponse beginning" d = defer.Deferred() d.addCallback(self.getResponse) d.addErrback(self.err) print "---- getDeferredResponse returning: ", d return d
Deferreds don't just automatically schedule themselves to be fired, they fire in response to some event. In other words some event must occur in which d.callback gets invoked.
Your code, as written, never causes the Deferred's callback to be fired.
In this example, you'd need to cause the callback to be invoked yourself, like so:
def getDeferredResponse(self): print "---- getDeferredResponse beginning" d = defer.Deferred() d.addCallback(self.getResponse) d.addErrback(self.err) print "---- getDeferredResponse returning: ", d reactor.callLater(1, d.callback, None) return d
Hope this helps,
L. Daniel Burr