1
"""Async web request example with tornado.
3
Requests to localhost:8888 will be relayed via 0MQ to a slow responder,
4
who will take 1-5 seconds to respond. The tornado app will remain responsive
5
duriung this time, and when the worker replies, the web request will finish.
7
A '.' is printed every 100ms to demonstrate that the zmq request is not blocking
18
from zmq.eventloop import ioloop, zmqstream
21
ioloop.install() must be called prior to instantiating *any* tornado objects,
22
and ideally before importing anything from tornado, just to be safe.
24
install() sets the singleton instance of tornado.ioloop.IOLoop with zmq's
25
IOLoop. If this is not done properly, multiple IOLoop instances may be
26
created, which will have the effect of some subset of handlers never being
27
called, because only one loop will be running.
33
from tornado import web
37
"""thread for slowly responding to replies."""
38
ctx = zmq.Context.instance()
39
socket = ctx.socket(zmq.REP)
41
socket.bind('tcp://127.0.0.1:5555')
45
print "\nworker received %r\n" % msg
46
time.sleep(random.randint(1,5))
47
socket.send(msg + " to you too, #%i" % i)
51
"""callback for showing that IOLoop is still responsive while we wait"""
58
class TestHandler(web.RequestHandler):
62
ctx = zmq.Context.instance()
63
s = ctx.socket(zmq.REQ)
64
s.connect('tcp://127.0.0.1:5555')
65
# send request to worker
67
loop = ioloop.IOLoop.instance()
68
self.stream = zmqstream.ZMQStream(s)
69
self.stream.on_recv(self.handle_reply)
71
def handle_reply(self, msg):
72
# finish web request with worker's reply
74
print "\nfinishing with %r\n" % reply,
80
worker = threading.Thread(target=slow_responder)
84
application = web.Application([(r"/", TestHandler)])
85
beat = ioloop.PeriodicCallback(dot, 100)
87
application.listen(8888)
89
ioloop.IOLoop.instance().start()
90
except KeyboardInterrupt:
94
if __name__ == "__main__":