On 6 Sep, 11:59 pm, [EMAIL PROTECTED] wrote:
I'd like to start streaming the document as soon as I start receiving
the results of the operation, but I'm stumped on how to actually
implement this. If I return a deferred from the render method, I cannot
fire this deferred until all of the rows have been built up.

Use a recursive generator that yields Deferreds for loading each row.

Here's an example - which I even looked at in a web browser :) - that should help to get you started. (The athena stuff is beside the point, it's just the quickest way I know to get a server serving a Nevow page...)

Warning: I haven't tested this on really large datasets, so it might have disastrous performance consequences. I don't *think* that it will, but I know there are some booby-traps in the rendering pipeline to snare the unwary.

# -- cut here for slow.py --
# Run quickly: twistd -n athena-widget --element slow.SlowElement

from twisted.internet import defer
from twisted.internet import reactor
from nevow.loaders import stan
from nevow.tags import div, directive
from nevow.athena import LiveElement
from nevow.page import renderer

def deferLater(n, result=None):
   """
   Why isn't this in Twisted yet?  Is it?
   """
   d = defer.Deferred()
   reactor.callLater(n, d.callback, result)
   return d


def delayedResults(results):
   """
   Yield results.... slowly.....
   """
   yield div[results.pop(0)]
   if results:
       def more(result):
           return delayedResults(results)
       yield deferLater(2.0).addCallback(more)


class SlowElement(LiveElement):
   """
   Render a list of 1 to 10 really slowly.
   """
   def start(self, ctx, data):
       """
       Give some data, wait for next result...
       """
       return delayedResults(map(str,range(10)))
   renderer(start)
   docFactory = stan(div(render=directive("start")))

_______________________________________________
Twisted-web mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

Reply via email to