From cce638a8adf4e045ca5505afea4bda57753c31dd Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Mon, 11 Aug 2014 16:33:29 -0400 Subject: initial import of debian package --- examples/eventloop/asyncweb.py | 96 ++++++++++++++++++++++++++++++++++++++++ examples/eventloop/echo.py | 27 +++++++++++ examples/eventloop/echostream.py | 24 ++++++++++ examples/eventloop/web.py | 46 +++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 examples/eventloop/asyncweb.py create mode 100644 examples/eventloop/echo.py create mode 100644 examples/eventloop/echostream.py create mode 100644 examples/eventloop/web.py (limited to 'examples/eventloop') diff --git a/examples/eventloop/asyncweb.py b/examples/eventloop/asyncweb.py new file mode 100644 index 0000000..06b03f3 --- /dev/null +++ b/examples/eventloop/asyncweb.py @@ -0,0 +1,96 @@ +"""Async web request example with tornado. + +Requests to localhost:8888 will be relayed via 0MQ to a slow responder, +who will take 1-5 seconds to respond. The tornado app will remain responsive +duriung this time, and when the worker replies, the web request will finish. + +A '.' is printed every 100ms to demonstrate that the zmq request is not blocking +the event loop. +""" + + +import sys +import random +import threading +import time + +import zmq +from zmq.eventloop import ioloop, zmqstream + +""" +ioloop.install() must be called prior to instantiating *any* tornado objects, +and ideally before importing anything from tornado, just to be safe. + +install() sets the singleton instance of tornado.ioloop.IOLoop with zmq's +IOLoop. If this is not done properly, multiple IOLoop instances may be +created, which will have the effect of some subset of handlers never being +called, because only one loop will be running. +""" + +ioloop.install() + +import tornado +from tornado import web + + +def slow_responder(): + """thread for slowly responding to replies.""" + ctx = zmq.Context.instance() + socket = ctx.socket(zmq.REP) + socket.linger = 0 + socket.bind('tcp://127.0.0.1:5555') + i=0 + while True: + msg = socket.recv() + print "\nworker received %r\n" % msg + time.sleep(random.randint(1,5)) + socket.send(msg + " to you too, #%i" % i) + i+=1 + +def dot(): + """callback for showing that IOLoop is still responsive while we wait""" + sys.stdout.write('.') + sys.stdout.flush() + +def printer(msg): + print (msg) + +class TestHandler(web.RequestHandler): + + @web.asynchronous + def get(self): + ctx = zmq.Context.instance() + s = ctx.socket(zmq.REQ) + s.connect('tcp://127.0.0.1:5555') + # send request to worker + s.send('hello') + loop = ioloop.IOLoop.instance() + self.stream = zmqstream.ZMQStream(s) + self.stream.on_recv(self.handle_reply) + + def handle_reply(self, msg): + # finish web request with worker's reply + reply = msg[0] + print "\nfinishing with %r\n" % reply, + self.stream.close() + self.write(reply) + self.finish() + +def main(): + worker = threading.Thread(target=slow_responder) + worker.daemon=True + worker.start() + + application = web.Application([(r"/", TestHandler)]) + beat = ioloop.PeriodicCallback(dot, 100) + beat.start() + application.listen(8888) + try: + ioloop.IOLoop.instance().start() + except KeyboardInterrupt: + print ' Interrupted' + + +if __name__ == "__main__": + main() + diff --git a/examples/eventloop/echo.py b/examples/eventloop/echo.py new file mode 100644 index 0000000..9be079b --- /dev/null +++ b/examples/eventloop/echo.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +"""A trivial ZMQ echo server using the eventloop. + +Authors +------- +* MinRK +""" + +import zmq +from zmq.eventloop import ioloop + +loop = ioloop.IOLoop.instance() + +ctx = zmq.Context() +s = ctx.socket(zmq.REP) +s.bind('tcp://127.0.0.1:5555') + +def rep_handler(sock, events): + # We don't know how many recv's we can do? + msg = sock.recv() + # No guarantee that we can do the send. We need a way of putting the + # send in the event loop. + sock.send(msg) + +loop.add_handler(s, rep_handler, zmq.POLLIN) + +loop.start() \ No newline at end of file diff --git a/examples/eventloop/echostream.py b/examples/eventloop/echostream.py new file mode 100644 index 0000000..04c1532 --- /dev/null +++ b/examples/eventloop/echostream.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +"""Adapted echo.py to put the send in the event loop using a ZMQStream. + +Authors +------- +* MinRK +""" + +import zmq +from zmq.eventloop import ioloop, zmqstream +loop = ioloop.IOLoop.instance() + +ctx = zmq.Context() +s = ctx.socket(zmq.REP) +s.bind('tcp://127.0.0.1:5555') +stream = zmqstream.ZMQStream(s, loop) + +def echo(msg): + print " ".join(msg) + stream.send_multipart(msg) + +stream.on_recv(echo) + +loop.start() \ No newline at end of file diff --git a/examples/eventloop/web.py b/examples/eventloop/web.py new file mode 100644 index 0000000..1285f95 --- /dev/null +++ b/examples/eventloop/web.py @@ -0,0 +1,46 @@ +import zmq +from zmq.eventloop import ioloop, zmqstream + +""" +ioloop.install() must be called prior to instantiating *any* tornado objects, +and ideally before importing anything from tornado, just to be safe. + +install() sets the singleton instance of tornado.ioloop.IOLoop with zmq's +IOLoop. If this is not done properly, multiple IOLoop instances may be +created, which will have the effect of some subset of handlers never being +called, because only one loop will be running. +""" + +ioloop.install() + +import tornado +import tornado.web + + +""" +this application can be used with echostream.py, start echostream.py, +start web.py, then every time you hit http://localhost:8888/, +echostream.py will print out 'hello' +""" + +def printer(msg): + print (msg) + +ctx = zmq.Context() +s = ctx.socket(zmq.REQ) +s.connect('tcp://127.0.0.1:5555') +stream = zmqstream.ZMQStream(s) +stream.on_recv(printer) + +class TestHandler(tornado.web.RequestHandler): + def get(self): + print ("sending hello") + stream.send("hello") + self.write("hello") +application = tornado.web.Application([(r"/", TestHandler)]) + +if __name__ == "__main__": + application.listen(8888) + ioloop.IOLoop.instance().start() + + -- cgit v1.2.3