技术开发 频道

twisted web开发中的异步实现方式

  【IT168 技术】作者在开发中遇到了twisted web中实现了异步的情况,尝试了通常的方法,行不通。在经过资料查阅之后,找到了正确的做法,方法如下:

  Here is an example with resources adapted from the Abe

  Fettig example on page 48 of "Twisted Network

  Programming Essentials." I am still getting my feet

  wet with resources. I intend to use this to help

  prototype REST support in WS-BPEL.

  Asynchronous Responses

  In all of the Twisted web server examples up to this point, we have assumed that the

  server can instantaneously respond to clients without having to first retrieve an expen‐

  sive resource (say, from a database query) or do expensive computation. What happens

  when responding to a request blocks?

  Example 4-9implements a dummy BusyPageresource that sleeps for five seconds before

  returning a response to the request.

  Example 4-9. blocking.py

    from twisted.internet import reactor
    from twisted.web.resource import Resource

    from twisted.web.server import Site
    import time
    class BusyPage(Resource):
        isLeaf = True
        def render_GET(self, request):
        time.sleep(5)
        return "Finally done, at %s" % (time.asctime(),)
    factory = Site(BusyPage())
    reactor.listenTCP(8000, factory)
    reactor.run()

  If you run this server and then load http://localhost:8000in several browser tabs in quick

  succession, you’ll observe that the last page to load will load N*5 seconds after the first

  page request, where N is the number of requests to the server. In other words, the

  requests are processed serially.

  This is terrible performance! We need our web server to be responding to other requests

  while an expensive resource is being processed.

  One of the great properties of this asynchronous framework is that we can achieve the

  responsiveness that we want without introducing threads by using the Deferred API

  we already know and love.

  Example 4-10demonstrates how to use a Deferredinstead of blocking on an expensive

  resource. deferLaterreplaces the blocking time.sleep(5)with a Deferred that will

  fire after five seconds, with a callback to _delayedRenderto finish the request when the

  fake resource becomes available. Then, instead of waiting on that resource, render_GET

  returns NOT_DONE_YETimmediately, freeing up the web server to process other requests.

  Example 4-10. non_blocking.py

    from twisted.internet import reactor
    from twisted.internet.task import deferLater
    from twisted.web.resource import Resource
    from twisted.web.server import Site, NOT_DONE_YET
    import time
    class BusyPage(Resource):
        isLeaf = True
        def _delayedRender(self, request):
            request.write("Finally done, at %s" % (time.asctime(),))
            request.finish()

        def render_GET(self, request):
            d = deferLater(reactor, 5, lambda: request)
            d.addCallback(self._delayedRender)
            return NOT_DONE_YET

    factory = Site(BusyPage())
    reactor.listenTCP(8000, factory)
    reactor.run()

  return NOT_DONE_YET

  factory = Site(BusyPage())

  reactor.listenTCP(8000, factory)

  reactor.run()

  ####################################################################

  以下代码案例来之这里

     class HomePage(resource.Resource):
       
        def doWork(self):
            message = """
            <html>
            <head>
            </head>
            <body>
            Hello World
            </body>
            </html>
            """
            self.request.write(message)
            self.request.finish()
           
           
        def render(self, request):
            self.request = request
            stackless.tasklet(self.doWork)()
            return server.NOT_DONE_YET

  and here is one with PyAMF .2

  class EchoServer(TwistedGateway):
  def __init__(self):
  super(EchoServer, self).__init__()
  self.request = None
  return
  def __echo__(self, request, deferred, y):
  print "=>", request, deferred, y
  deferred.callback(y)
  def echo(self, request, y):
  print "=>", request, y
  deferred = defer.Deferred()
  stackless.tasklet(self.__echo__)(request,deferred, y)
  return deferred

0
相关文章