@@ -161,9 +161,10 @@ <h3 class="author">
161161</ ul >
162162</ li >
163163< li > < a href ="#real-world-applications "> Real World Applications</ a > < ul >
164- < li > < a href ="#green -zeromq "> Green ZeroMQ</ a > </ li >
164+ < li > < a href ="#gevent -zeromq "> Gevent ZeroMQ</ a > </ li >
165165< li > < a href ="#wsgi-servers "> WSGI Servers</ a > </ li >
166166< li > < a href ="#long-polling "> Long Polling</ a > </ li >
167+ < li > < a href ="#websockets "> Websockets</ a > </ li >
167168< li > < a href ="#chat-server "> Chat Server</ a > </ li >
168169< li > < a href ="#license "> License</ a > </ li >
169170</ ul >
@@ -312,15 +313,15 @@ <h2 id="synchronous-asynchronous-execution">Synchronous & Asynchronous Execu
312313Task 9 done
313314Asynchronous:
314315Task 1 done
315- Task 2 done
316+ Task 5 done
317+ Task 4 done
318+ Task 8 done
316319Task 6 done
320+ Task 9 done
321+ Task 0 done
317322Task 3 done
318- Task 4 done
323+ Task 2 done
319324Task 7 done
320- Task 0 done
321- Task 9 done
322- Task 8 done
323- Task 5 done
324325</ pre > </ code > </ p >
325326< p > In the synchronous case all the tasks are run sequentially,
326327which results in the main programming < em > blocking</ em > (
@@ -943,7 +944,75 @@ <h2 id="actors">Actors</h2>
943944</ pre >
944945
945946< h1 id ="real-world-applications "> Real World Applications</ h1 >
946- < h2 id ="green-zeromq "> Green ZeroMQ</ h2 >
947+ < h2 id ="gevent-zeromq "> Gevent ZeroMQ</ h2 >
948+ < p > < a href ="http://www.zeromq.org/ "> ZeroMQ</ a > is described by its authors as
949+ "a socket library that acts as a concurrency framework". It is a
950+ very powerful messaging layer for building concurrent and
951+ distributed applications. </ p >
952+ < p > ZeroMQ provides a variety of socket primitives, the simplest of
953+ which being a Request-Response socket pair. A socket has two
954+ methods of interest < code > send</ code > and < code > recv</ code > , both of which are
955+ normally blocking operations. But this is remedied by a briliant
956+ library by < a href ="https://github.com/traviscline "> Travis Cline</ a > which
957+ uses gevent.socket to poll ZeroMQ sockets in a non-blocking
958+ manner. You can install gevent-zeromq from PyPi via: < code > pip install
959+ gevent-zeromq</ code > </ p >
960+ < pre > < code class ="python ">
961+ # Note: Remember to ``pip install pyzmq gevent_zeromq``
962+ from gevent_zeromq import zmq
963+
964+ # Global Context
965+ context = zmq.Context()
966+
967+ def server():
968+ server_socket = context.socket(zmq.REQ)
969+ server_socket.bind("tcp://*:5000")
970+
971+ for request in range(1,10):
972+ server_socket.send("Hello")
973+ print('Switched to Server for ', request)
974+ # Implicit context switch occurs here
975+ server_socket.recv()
976+
977+ def client():
978+ client_socket = context.socket(zmq.REP)
979+ client_socket.connect("tcp://*:5000")
980+
981+ for request in range(1,10):
982+
983+ client_socket.recv()
984+ print('Switched to Client for ', request)
985+ # Implicit context switch occurs here
986+ client_socket.send("World")
987+
988+ publisher = gevent.spawn(server),
989+ client = gevent.spawn(client),
990+
991+ gevent.joinall( publisher + client )
992+
993+ </ pre >
994+
995+ < p > </ code >
996+ < pre > < code class ="python ">
997+ Switched to Server for 1
998+ Switched to Client for 1
999+ Switched to Server for 2
1000+ Switched to Client for 2
1001+ Switched to Server for 3
1002+ Switched to Client for 3
1003+ Switched to Server for 4
1004+ Switched to Client for 4
1005+ Switched to Server for 5
1006+ Switched to Client for 5
1007+ Switched to Server for 6
1008+ Switched to Client for 6
1009+ Switched to Server for 7
1010+ Switched to Client for 7
1011+ Switched to Server for 8
1012+ Switched to Client for 8
1013+ Switched to Server for 9
1014+ Switched to Client for 9
1015+ </ pre > </ code > </ p >
9471016< h2 id ="wsgi-servers "> WSGI Servers</ h2 >
9481017< pre >
9491018< code class ="python "> from gevent.pywsgi import WSGIServer
@@ -971,6 +1040,39 @@ <h2 id="wsgi-servers">WSGI Servers</h2>
9711040</ pre >
9721041
9731042< h2 id ="long-polling "> Long Polling</ h2 >
1043+ < pre >
1044+ < code class ="python "> from gevent.queue import Queue, Empty
1045+ from gevent.pywsgi import WSGIServer
1046+
1047+ data_source = Queue()
1048+
1049+ def producer():
1050+ while True:
1051+ data_source.put_nowait('Hello World')
1052+ gevent.sleep(1)
1053+
1054+ def ajax_endpoint(environ, start_response):
1055+ status = '200 OK'
1056+ headers = [
1057+ ('Content-Type', 'application/json')
1058+ ]
1059+
1060+ try:
1061+ datum = data_source.get(timeout=5)
1062+ except Empty:
1063+ datum = []
1064+
1065+ start_response(status, headers)
1066+ return json.dumps(datum)
1067+
1068+ gevent.spawn(producer)
1069+
1070+ WSGIServer(('', 8000), ajax_endpoint).serve_forever()
1071+
1072+ </ code >
1073+ </ pre >
1074+
1075+ < h2 id ="websockets "> Websockets</ h2 >
9741076< h2 id ="chat-server "> Chat Server</ h2 >
9751077< p > The final motivating example, a realtime chat room. This example
9761078requires < a href ="http://flask.pocoo.org/ "> Flask</ a > ( but not neccesarily so, you could use Django,
@@ -990,6 +1092,13 @@ <h2 id="chat-server">Chat Server</h2>
9901092app = Flask(__name__)
9911093app.debug = True
9921094
1095+ rooms = {
1096+ 'topic1': Room(),
1097+ 'topic2': Room(),
1098+ }
1099+
1100+ users = {}
1101+
9931102class Room(object):
9941103
9951104 def __init__(self):
@@ -1013,13 +1122,6 @@ <h2 id="chat-server">Chat Server</h2>
10131122 def __init__(self):
10141123 self.queue = queue.Queue()
10151124
1016- rooms = {
1017- 'foo': Room(),
1018- 'bar': Room(),
1019- }
1020-
1021- users = {}
1022-
10231125@app.route('/')
10241126def choose_name():
10251127 return render_template('choose.html')
0 commit comments