Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5096373
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2015-08-19 19:45:09

在开发中 遇到了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

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

  3. from twisted.web.server import Site
  4. import time
  5. class BusyPage(Resource):
  6.     isLeaf = True
  7.     def render_GET(self, request):
  8.     time.sleep(5)
  9.     return "Finally done, at %s" % (time.asctime(),)
  10. factory = Site(BusyPage())
  11. reactor.listenTCP(8000, factory)
  12. reactor.run()
If you run this server and then load   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


  1. from twisted.internet import reactor
  2. from twisted.internet.task import deferLater
  3. from twisted.web.resource import Resource
  4. from twisted.web.server import Site, NOT_DONE_YET
  5. import time
  6. class BusyPage(Resource):
  7.     isLeaf = True
  8.     def _delayedRender(self, request):
  9.         request.write("Finally done, at %s" % (time.asctime(),))
  10.         request.finish()

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

  15. factory = Site(BusyPage())
  16. reactor.listenTCP(8000, factory)
  17. reactor.run()
####################################################################

以下代码案例来之这里

  1. class HomePage(resource.Resource):
  2.     
  3.     def doWork(self):
  4.         message = """
  5.         <html>
  6.         <head>
  7.         </head>
  8.         <body>
  9.         Hello World
  10.         </body>
  11.         </html>
  12.         """
  13.         self.request.write(message)
  14.         self.request.finish()
  15.         
  16.         
  17.     def render(self, request):
  18.         self.request = request
  19.         stackless.tasklet(self.doWork)()
  20.         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


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




补充: 用twisted来做web开发很不方便,推荐用另外一个基于twisted和tornado实现的web框架cyclone 。
包括本文所提到的异步问题,实现起来也相当简单。
再次放一个cyclone实现的web异步小demo代码


from twisted.internet import reactor  
class MyRequestHandler(web.RequestHandler): 
    @web.asynchronous
    def get(self): 
        self.write("Processing your request...") 
        reactor.callLater(5, self.do_something) 
    def do_something(self): 
        self.finish("done!") 

 

客户端请求一次,服务器可返回多次。 










                                   
阅读(4470) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~