[Twisted-Python] Woven View factories: defered rendering?

Hi, I have a webpage, that is rendered via twisted.web.woven.page.Page class. In one of it's wvfactory_ methods, I need to send an e-mail. I would also like to check if sending of the e-mail was successful (eg. mailserver is up, running, and reachable via network). I thought about something like this: def wvfactory_render(self, req, node, model): # do some stuff sendEMail().addCallbacks(self.emailOkay, self.emailFailure) return # what should I return here? def emailOkay(self, *args): # render "thank you, e-mail sent" message def emailFailure(self, *args): # render "error" message My questions: 1) is it a good, Twisted Python way to do this? If not, a) what would be the correct one? b) can you point me to some docs? 2) if it is a good way: a) is it implemented? if yes: 1) what should I return from wvfactory_render? 2) what parameters would be passed to callbacks then? b) if not, do you think it would be worth implementing? I have seen something similar like the thing I want to code in some example sources: def render(...): [ launch some callbacks ] return server.NOT_DONE_YET ... but they were about Resource class, and I'm using Page here. Anyone? Regards, -- Michal Pasternak :: http://pasternak.w.lub.pl

Philippe Lafoucri?re [Thu, Nov 20, 2003 at 11:04:31AM +0100]:
Same problem here, and I didn't find a solution. This should to the woven faq I think.
As I am a very, very lazy man, I'd like to hear from at least one Twisted developer, that it's currently impossible (or unwise to do that) before trying to implement such functionality. ... and I wonder if it's different for nevow. -- Michal Pasternak :: http://pasternak.w.lub.pl

On Thu, 2003-11-20 at 05:25, Michal Pasternak wrote:
Well, it's possible to do if you are willing to do some legwork yourself. If you override the render method of your Page, you can manually handle waiting for the Deferred stuff to finish, because in a Resource's render you can return NOT_DONE_YET and then call request.finish() at a later time. I've done that successfully. nevow handles all this stuff much more smoothly. I wouldn't put a lot of work into extending woven. b.g.

On Nov 19, 2003, at 10:20 PM, Michal Pasternak wrote:
<snip> Woven has some, ahem, object identity issues. It really, really wants you to return an actual View instance from a wvfactory_. However, it does support deferreds being returned from the Widget.generate method. A deferred callback should mutate the incoming template node in place in order to cause some changes to the final page: class MyDeferredWidget(widgets.Widget): def generate(self, request, node): theDeferred = doSomeAction() def theCallback(result): node.appendChild( request.d.createTextNode("the result was: %s" % result) ) theDeferred.addCallback(theCallback) return theDeferred class MyPage(page.Page): template = """<html><span view="theDeferredThing" /></html>""" def wvfactory_theDeferredThing(self, request, node, model): return MyDeferredWidget(model) This is completely untested, but it gives you an idea of what to do. One of the main reasons for embarking upon nevow was that I knew a lot more about Deferreds than when I wrote woven, and woven's architecture made it very difficult to support deferreds properly. In nevow, the code might look like: class MyPage(renderer.Renderer): def render_doSomeAction(self, context, data): return doSomeAction().addCallback( lambda result: "The result was: %s" % result) document = html[ span[ render_doSomeAction ] ] The point is nevow was designed from the beginning to handle Deferreds more gracefully than woven was. Also, because the paradigm in nevow sticks far better to "the return value of a callable replaces whatever came in" than woven ended up doing, it's impossible to get into funny identity situations where you're mutating an object but you don't see the result of it in the final page, because you were mutating a copy and it was the wrong object. dp

Philippe Lafoucri?re [Thu, Nov 20, 2003 at 11:04:31AM +0100]:
Same problem here, and I didn't find a solution. This should to the woven faq I think.
As I am a very, very lazy man, I'd like to hear from at least one Twisted developer, that it's currently impossible (or unwise to do that) before trying to implement such functionality. ... and I wonder if it's different for nevow. -- Michal Pasternak :: http://pasternak.w.lub.pl

On Thu, 2003-11-20 at 05:25, Michal Pasternak wrote:
Well, it's possible to do if you are willing to do some legwork yourself. If you override the render method of your Page, you can manually handle waiting for the Deferred stuff to finish, because in a Resource's render you can return NOT_DONE_YET and then call request.finish() at a later time. I've done that successfully. nevow handles all this stuff much more smoothly. I wouldn't put a lot of work into extending woven. b.g.

On Nov 19, 2003, at 10:20 PM, Michal Pasternak wrote:
<snip> Woven has some, ahem, object identity issues. It really, really wants you to return an actual View instance from a wvfactory_. However, it does support deferreds being returned from the Widget.generate method. A deferred callback should mutate the incoming template node in place in order to cause some changes to the final page: class MyDeferredWidget(widgets.Widget): def generate(self, request, node): theDeferred = doSomeAction() def theCallback(result): node.appendChild( request.d.createTextNode("the result was: %s" % result) ) theDeferred.addCallback(theCallback) return theDeferred class MyPage(page.Page): template = """<html><span view="theDeferredThing" /></html>""" def wvfactory_theDeferredThing(self, request, node, model): return MyDeferredWidget(model) This is completely untested, but it gives you an idea of what to do. One of the main reasons for embarking upon nevow was that I knew a lot more about Deferreds than when I wrote woven, and woven's architecture made it very difficult to support deferreds properly. In nevow, the code might look like: class MyPage(renderer.Renderer): def render_doSomeAction(self, context, data): return doSomeAction().addCallback( lambda result: "The result was: %s" % result) document = html[ span[ render_doSomeAction ] ] The point is nevow was designed from the beginning to handle Deferreds more gracefully than woven was. Also, because the paradigm in nevow sticks far better to "the return value of a callable replaces whatever came in" than woven ended up doing, it's impossible to get into funny identity situations where you're mutating an object but you don't see the result of it in the final page, because you were mutating a copy and it was the wrong object. dp
participants (4)
-
Bill Gribble
-
Donovan Preston
-
Michal Pasternak
-
Philippe Lafoucrière