Skip to content

Commit ee9d3ea

Browse files
committed
Added ZeroMQ section.
1 parent 87d79f1 commit ee9d3ea

2 files changed

Lines changed: 209 additions & 23 deletions

File tree

index.html

Lines changed: 117 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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 &amp; Asynchronous Execu
312313
Task 9 done
313314
Asynchronous:
314315
Task 1 done
315-
Task 2 done
316+
Task 5 done
317+
Task 4 done
318+
Task 8 done
316319
Task 6 done
320+
Task 9 done
321+
Task 0 done
317322
Task 3 done
318-
Task 4 done
323+
Task 2 done
319324
Task 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,
326327
which 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
9761078
requires <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>
9901092
app = Flask(__name__)
9911093
app.debug = True
9921094

1095+
rooms = {
1096+
'topic1': Room(),
1097+
'topic2': Room(),
1098+
}
1099+
1100+
users = {}
1101+
9931102
class 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('/')
10241126
def choose_name():
10251127
return render_template('choose.html')

tutorial.md

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,57 @@ gevent.joinall([ping, pong])
705705

706706
# Real World Applications
707707

708-
## Green ZeroMQ
708+
## Gevent ZeroMQ
709+
710+
[ZeroMQ](http://www.zeromq.org/) is described by its authors as
711+
"a socket library that acts as a concurrency framework". It is a
712+
very powerful messaging layer for building concurrent and
713+
distributed applications.
714+
715+
ZeroMQ provides a variety of socket primitives, the simplest of
716+
which being a Request-Response socket pair. A socket has two
717+
methods of interest ``send`` and ``recv``, both of which are
718+
normally blocking operations. But this is remedied by a briliant
719+
library by [Travis Cline](https://github.com/traviscline) which
720+
uses gevent.socket to poll ZeroMQ sockets in a non-blocking
721+
manner. You can install gevent-zeromq from PyPi via: ``pip install
722+
gevent-zeromq``
723+
724+
[[[cog
725+
# Note: Remember to ``pip install pyzmq gevent_zeromq``
726+
from gevent_zeromq import zmq
727+
728+
# Global Context
729+
context = zmq.Context()
730+
731+
def server():
732+
server_socket = context.socket(zmq.REQ)
733+
server_socket.bind("tcp://*:5000")
734+
735+
for request in range(1,10):
736+
server_socket.send("Hello")
737+
print('Switched to Server for ', request)
738+
# Implicit context switch occurs here
739+
server_socket.recv()
740+
741+
def client():
742+
client_socket = context.socket(zmq.REP)
743+
client_socket.connect("tcp://*:5000")
744+
745+
for request in range(1,10):
746+
747+
client_socket.recv()
748+
print('Switched to Client for ', request)
749+
# Implicit context switch occurs here
750+
client_socket.send("World")
751+
752+
publisher = gevent.spawn(server),
753+
client = gevent.spawn(client),
754+
755+
gevent.joinall( publisher + client )
756+
757+
]]]
758+
[[[end]]]
709759

710760
## WSGI Servers
711761

@@ -737,6 +787,40 @@ Performance on Gevent servers is phenomenal.
737787

738788
## Long Polling
739789

790+
<pre>
791+
<code class="python">from gevent.queue import Queue, Empty
792+
from gevent.pywsgi import WSGIServer
793+
794+
data_source = Queue()
795+
796+
def producer():
797+
while True:
798+
data_source.put_nowait('Hello World')
799+
gevent.sleep(1)
800+
801+
def ajax_endpoint(environ, start_response):
802+
status = '200 OK'
803+
headers = [
804+
('Content-Type', 'application/json')
805+
]
806+
807+
try:
808+
datum = data_source.get(timeout=5)
809+
except Empty:
810+
datum = []
811+
812+
start_response(status, headers)
813+
return json.dumps(datum)
814+
815+
gevent.spawn(producer)
816+
817+
WSGIServer(('', 8000), ajax_endpoint).serve_forever()
818+
819+
</code>
820+
</pre>
821+
822+
## Websockets
823+
740824
## Chat Server
741825

742826
The final motivating example, a realtime chat room. This example
@@ -759,6 +843,13 @@ import simplejson as json
759843
app = Flask(__name__)
760844
app.debug = True
761845

846+
rooms = {
847+
'topic1': Room(),
848+
'topic2': Room(),
849+
}
850+
851+
users = {}
852+
762853
class Room(object):
763854

764855
def __init__(self):
@@ -782,13 +873,6 @@ class User(object):
782873
def __init__(self):
783874
self.queue = queue.Queue()
784875

785-
rooms = {
786-
'foo': Room(),
787-
'bar': Room(),
788-
}
789-
790-
users = {}
791-
792876
@app.route('/')
793877
def choose_name():
794878
return render_template('choose.html')

0 commit comments

Comments
 (0)