2012-03-24 16 views
0

Ich dachte nur über die blockierungsfreie Infrastruktur von Tornado und Event-Driven-Programmierung. Eigentlich schreibe ich eine einfache Webapp, die auf eine HTTP-API eines externen Webservice zugreift. Ich verstehe, warum ich diese API nicht blockierend nennen sollte. Aber gibt es irgendwelche Nachteile wenn ich nur den ersten Anruf nicht blockierend mache, damit der IOLoop weiterschleifen kann?Tornado Blocking Code

Beispiel:

@tornado.web.asynchronous 
def get(self): 
    nonblocking_call1(self._callback) 

def _callback(self, response): 
    self.write(str(response)) 
    self.write(str(blocking_call2())) 
    self.write(str(blocking_call3())) 
    self.finish() 

gegen

@tornado.web.asynchronous 
def get(self): 
    nonblocking_call1(self._nonblocking_callback1) 

def _callback1(self, response): 
    self.write(str(response)) 
    nonblocking_call2(self._nonblocking_callback2) 

def _callback2(self, response): 
    self.write(str(response)) 
    nonblocking_call3(self._nonblocking_callback3) 

def _callback3(self, response): 
    self.write(str(response)) 
    self.finish() 

Antwort

1

Wenn Sie Code innerhalb Tornado verwenden zu blockieren, die gleiche Tornado Prozess nicht Prozess alle anderen Anfragen während jeder Sperrcode wartet. Ihre App unterstützt nicht mehr als einen gleichzeitigen Benutzer, und selbst wenn der blockierende Anruf nur etwa 100 ms dauert, ist er immer noch ein RIESIGER Leistungskiller.

Wenn das Schreiben auf diese Weise für Sie ist anstrengend (es ist für mich), können Sie Tornado des gen Modul verwenden:

class GenAsyncHandler(RequestHandler): 
    @asynchronous 
    @gen.engine 
    def get(self): 
     http_client = AsyncHTTPClient() 
     response = yield gen.Task(http_client.fetch, "http://example.com") 
     do_something_with_response(response) 
     self.render("template.html")