From 976f18e922219200f090966c43b26438b9f5a019 Mon Sep 17 00:00:00 2001 From: Alexander James Phillips Date: Wed, 5 Jun 2013 16:43:37 +0100 Subject: [PATCH 01/38] remove trailing whitespace --- index.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index f16245c..b1b8adb 100644 --- a/index.html +++ b/index.html @@ -90,7 +90,7 @@

Introduction

your existing concurrency problems and start writing asynchronous applications today.

Contributors

-

In chronological order of contribution: +

In chronological order of contribution: Stephen Diehl Jérémy Bethmont sww @@ -268,7 +268,7 @@

Synchronous & Asynchronous Execu while each task executes.

The important parts of the program are the gevent.spawn which wraps up the given function -inside of a Greenlet thread. The list of initialized greenlets +inside of a Greenlet thread. The list of initialized greenlets are stored in the array threads which is passed to the gevent.joinall function which blocks the current program to run all the given greenlets. The execution will step @@ -397,7 +397,7 @@

Spawning Greenlets

# foo thread1 = Greenlet.spawn(foo, "Hello", 1) -# Wrapper for creating and runing a new Greenlet from the named +# Wrapper for creating and runing a new Greenlet from the named # function foo, with the passed arguments thread2 = gevent.spawn(foo, "I live!", 2) @@ -698,7 +698,7 @@

Events

A extension of the Event object is the AsyncResult which allows you to send a value along with the wakeup call. This is -sometimes called a future or a deferred, since it holds a +sometimes called a future or a deferred, since it holds a reference to a future value that can be set on an arbitrary time schedule.

@@ -794,7 +794,7 @@ 

Queues

Queues can also block on either put or get as the need arises.

Each of the put and get operations has a non-blocking -counterpart, put_nowait and +counterpart, put_nowait and get_nowait which will not block, but instead raise either gevent.queue.Empty or gevent.queue.Full in the operation is not possible.

@@ -1375,7 +1375,7 @@

Gevent ZeroMQ

Simple Servers

 
-# On Unix: Access with ``$ nc 127.0.0.1 5000`` 
+# On Unix: Access with ``$ nc 127.0.0.1 5000``
 # On Window: Access with ``$ telnet 127.0.0.1 5000``
 
 from gevent.server import StreamServer
@@ -1469,8 +1469,8 @@ 

Streaming Servers

But regardless, performance on Gevent servers is phenomenal compared to other Python servers. libev is a very vetted technology and its derivative servers are known to perform well at scale.

-

To benchmark, try Apache Benchmark ab or see this -Benchmark of Python WSGI Servers +

To benchmark, try Apache Benchmark ab or see this +Benchmark of Python WSGI Servers for comparison with other servers.

 $ ab -n 10000 -c 100 http://127.0.0.1:8000/

From 9be98060948fe9459ee3dbe873377fbfcfe89133 Mon Sep 17 00:00:00 2001
From: Alexander James Phillips 
Date: Wed, 5 Jun 2013 16:47:08 +0100
Subject: [PATCH 02/38] minor spelling mistake and grammar

---
 index.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/index.html b/index.html
index b1b8adb..f7de00c 100644
--- a/index.html
+++ b/index.html
@@ -797,8 +797,8 @@ 

Queues

counterpart, put_nowait and get_nowait which will not block, but instead raise either gevent.queue.Empty or -gevent.queue.Full in the operation is not possible.

-

In this example we have the boss running simultaneously to the +gevent.queue.Full if the operation is not possible.

+

In the example below we have the boss running simultaneously to the workers and have a restriction on the Queue preventing it from containing more than three elements. This restriction means that the put operation will block until there is space on the queue. From dccfea210f34a45fe2cc34bf954693a4e597eafc Mon Sep 17 00:00:00 2001 From: Ramiro Morales Date: Thu, 18 Jul 2013 15:50:19 -0300 Subject: [PATCH 03/38] Update tutorial.md --- tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial.md b/tutorial.md index 5940fe5..b55df5d 100644 --- a/tutorial.md +++ b/tutorial.md @@ -117,7 +117,7 @@ def gr2(): print('Ended Polling: ', tic()) def gr3(): - print("Hey lets do some stuff while the greenlets poll, at", tic()) + print("Hey lets do some stuff while the greenlets poll, ", tic()) gevent.sleep(1) gevent.joinall([ From 38a20c7f89ed77116ec70121f87b344bbed1b248 Mon Sep 17 00:00:00 2001 From: Philip Damra Date: Fri, 19 Jul 2013 09:07:41 -0400 Subject: [PATCH 04/38] Update tutorial.md The example illustrating the use of gevent.event.Event mistakenly used AsyncResult --- tutorial.md | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/tutorial.md b/tutorial.md index b55df5d..15c51a3 100644 --- a/tutorial.md +++ b/tutorial.md @@ -576,29 +576,40 @@ Greenlets.

 import gevent
-from gevent.event import AsyncResult
+from gevent.event import Event
 
-a = AsyncResult()
+'''
+Illustrates the use of events
+'''
 
-def setter():
-    """
-    After 3 seconds set wake all threads waiting on the value of
-    a.
-    """
-    gevent.sleep(3)
-    a.set()
 
-def waiter():
-    """
-    After 3 seconds the get call will unblock.
-    """
-    a.get() # blocking
-    print 'I live!'
+evt = Event()
 
-gevent.joinall([
-    gevent.spawn(setter),
-    gevent.spawn(waiter),
-])
+def setter():
+    '''After 3 seconds, wake all threads waiting on the value of evt'''
+	print('A: Hey wait for me, I have to do something')
+	gevent.sleep(3)
+	print("Ok, I'm done")
+	evt.set()
+	
+	
+def waiter():
+	'''After 3 seconds the get call will unblock'''
+	print("I'll wait for you")
+	evt.wait()  # blocking
+	print("It's about time")
+	
+def main():
+	gevent.joinall([
+		gevent.spawn(setter),
+		gevent.spawn(waiter),
+		gevent.spawn(waiter),
+		gevent.spawn(waiter),
+		gevent.spawn(waiter),
+		gevent.spawn(waiter)
+	])
+
+if __name__ == '__main__': main()
 
 
 
From 10f9bcffec69f7426a7b888e56f62b58ad0535c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Marques=20Vieira?= Date: Fri, 19 Jul 2013 16:35:41 +0100 Subject: [PATCH 05/38] Trimmed trailing whitespace --- tutorial.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tutorial.md b/tutorial.md index 15c51a3..56a3306 100644 --- a/tutorial.md +++ b/tutorial.md @@ -11,7 +11,7 @@ applications today. ### Contributors -In chronological order of contribution: +In chronological order of contribution: [Stephen Diehl](http://www.stephendiehl.com) [Jérémy Bethmont](https://github.com/jerem) [sww](https://github.com/sww) @@ -41,7 +41,7 @@ This page is also [available in Japanese](http://methane.github.com/gevent-tutor The primary pattern used in gevent is the Greenlet, a lightweight coroutine provided to Python as a C extension module. Greenlets all run inside of the OS process for the main -program but are scheduled cooperatively. +program but are scheduled cooperatively. > Only one greenlet is ever running at any given time. @@ -169,7 +169,7 @@ while each task executes. The important parts of the program are the ``gevent.spawn`` which wraps up the given function -inside of a Greenlet thread. The list of initialized greenlets +inside of a Greenlet thread. The list of initialized greenlets are stored in the array ``threads`` which is passed to the ``gevent.joinall`` function which blocks the current program to run all the given greenlets. The execution will step @@ -308,7 +308,7 @@ def foo(message, n): # foo thread1 = Greenlet.spawn(foo, "Hello", 1) -# Wrapper for creating and running a new Greenlet from the named +# Wrapper for creating and running a new Greenlet from the named # function foo, with the passed arguments thread2 = gevent.spawn(foo, "I live!", 2) @@ -591,14 +591,14 @@ def setter(): gevent.sleep(3) print("Ok, I'm done") evt.set() - - + + def waiter(): '''After 3 seconds the get call will unblock''' print("I'll wait for you") evt.wait() # blocking print("It's about time") - + def main(): gevent.joinall([ gevent.spawn(setter), @@ -616,7 +616,7 @@ if __name__ == '__main__': main() A extension of the Event object is the AsyncResult which allows you to send a value along with the wakeup call. This is -sometimes called a future or a deferred, since it holds a +sometimes called a future or a deferred, since it holds a reference to a future value that can be set on an arbitrary time schedule. @@ -685,10 +685,10 @@ gevent.joinall([ ]]] [[[end]]] -Queues can also block on either ``put`` or ``get`` as the need arises. +Queues can also block on either ``put`` or ``get`` as the need arises. Each of the ``put`` and ``get`` operations has a non-blocking -counterpart, ``put_nowait`` and +counterpart, ``put_nowait`` and ``get_nowait`` which will not block, but instead raise either ``gevent.queue.Empty`` or ``gevent.queue.Full`` in the operation is not possible. @@ -1084,7 +1084,7 @@ by the language Erlang. In short the main idea is that you have a collection of independent Actors which have an inbox from which they receive messages from other Actors. The main loop inside the Actor iterates through its messages and takes action according to -its desired behavior. +its desired behavior. Gevent does not have a primitive Actor type, but we can define one very simply using a Queue inside of a subclassed Greenlet. @@ -1153,7 +1153,7 @@ gevent.joinall([ping, pong]) [ZeroMQ](http://www.zeromq.org/) is described by its authors as "a socket library that acts as a concurrency framework". It is a very powerful messaging layer for building concurrent and -distributed applications. +distributed applications. ZeroMQ provides a variety of socket primitives, the simplest of which being a Request-Response socket pair. A socket has two @@ -1205,8 +1205,8 @@ gevent.joinall([publisher, client])
 
-# On Unix: Access with ``$ nc 127.0.0.1 5000`` 
-# On Window: Access with ``$ telnet 127.0.0.1 5000`` 
+# On Unix: Access with ``$ nc 127.0.0.1 5000``
+# On Window: Access with ``$ telnet 127.0.0.1 5000``
 
 from gevent.server import StreamServer
 
@@ -1231,7 +1231,7 @@ Henceforth called ``wsgi`` and ``pywsgi``:
 
 In earlier versions of gevent before 1.0.x, gevent used libevent
 instead of libev. Libevent included a fast HTTP server which was
-used by gevent's ``wsgi`` server. 
+used by gevent's ``wsgi`` server.
 
 In gevent 1.0.x there is no http server included. Instead
 ``gevent.wsgi`` is now an alias for the pure Python server in
@@ -1281,7 +1281,7 @@ def application(environ, start_response):
 WSGIServer(('', 8000), application).serve_forever()
 
 
-
+
Using pywsgi we can however write our handler as a generator and yield the result chunk by chunk. @@ -1303,20 +1303,20 @@ def application(environ, start_response): WSGIServer(('', 8000), application).serve_forever() -
+ But regardless, performance on Gevent servers is phenomenal compared to other Python servers. libev is a very vetted technology and its derivative servers are known to perform well at scale. -To benchmark, try Apache Benchmark ``ab`` or see this -[Benchmark of Python WSGI Servers](http://nichol.as/benchmark-of-python-web-servers) +To benchmark, try Apache Benchmark ``ab`` or see this +[Benchmark of Python WSGI Servers](http://nichol.as/benchmark-of-python-web-servers) for comparison with other servers.
 $ ab -n 10000 -c 100 http://127.0.0.1:8000/
 
-
+ ## Long Polling From afaaf45393ef7cde0b467c316704de068a03f77e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Marques=20Vieira?= Date: Fri, 19 Jul 2013 16:57:01 +0100 Subject: [PATCH 06/38] Ran build once since there were unbuilt modifications --- index.html | 83 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/index.html b/index.html index f7de00c..8bc255b 100644 --- a/index.html +++ b/index.html @@ -114,7 +114,7 @@

Greenlets

The primary pattern used in gevent is the Greenlet, a lightweight coroutine provided to Python as a C extension module. Greenlets all run inside of the OS process for the main -program but are scheduled cooperatively.

+program but are scheduled cooperatively.

Only one greenlet is ever running at any given time.

@@ -188,7 +188,7 @@

Synchronous & Asynchronous Execu print('Ended Polling: ', tic()) def gr3(): - print("Hey lets do some stuff while the greenlets poll, at", tic()) + print("Hey lets do some stuff while the greenlets poll, ", tic()) gevent.sleep(1) gevent.joinall([ @@ -202,7 +202,7 @@

Synchronous & Asynchronous Execu

 Started Polling:  at 0.0 seconds
 Started Polling:  at 0.0 seconds
-Hey lets do some stuff while the greenlets poll, at at 0.0 seconds
+Hey lets do some stuff while the greenlets poll,  at 0.0 seconds
 Ended Polling:  at 2.0 seconds
 Ended Polling:  at 2.0 seconds
 

@@ -251,16 +251,16 @@

Synchronous & Asynchronous Execu Task 8 done Task 9 done Asynchronous: -Task 1 done -Task 2 done +Task 3 done Task 7 done +Task 2 done Task 6 done Task 5 done +Task 4 done Task 0 done -Task 3 done +Task 1 done Task 8 done Task 9 done -Task 4 done

In the synchronous case all the tasks are run sequentially, which results in the main programming blocking ( @@ -397,7 +397,7 @@

Spawning Greenlets

# foo thread1 = Greenlet.spawn(foo, "Hello", 1) -# Wrapper for creating and runing a new Greenlet from the named +# Wrapper for creating and running a new Greenlet from the named # function foo, with the passed arguments thread2 = gevent.spawn(foo, "I live!", 2) @@ -614,10 +614,10 @@

Timeouts

Monkeypatching

Alas we come to dark corners of Gevent. I've avoided mentioning monkey patching up until now to try and motivate the powerful -coroutine patterns but the time has come to discuss the dark arts -of monkey-patching. If you noticed above we invoked the commnad +coroutine patterns, but the time has come to discuss the dark arts +of monkey-patching. If you noticed above we invoked the command monkey.patch_socket(). This is a purely side-effectful command to -modify the standard library's socket library

+modify the standard library's socket library.

 import socket
 print( socket.socket )
@@ -669,29 +669,38 @@ 

Events

Greenlets.

 import gevent
-from gevent.event import AsyncResult
+from gevent.event import Event
 
-a = AsyncResult()
+'''
+Illustrates the use of events
+'''
+
+evt = Event()
 
 def setter():
-    """
-    After 3 seconds set wake all threads waiting on the value of
-    a.
-    """
+    '''After 3 seconds, wake all threads waiting on the value of evt'''
+    print('A: Hey wait for me, I have to do something')
     gevent.sleep(3)
-    a.set()
+    print("Ok, I'm done")
+    evt.set()
 
 def waiter():
-    """
-    After 3 seconds the get call will unblock.
-    """
-    a.get() # blocking
-    print 'I live!'
-
-gevent.joinall([
-    gevent.spawn(setter),
-    gevent.spawn(waiter),
-])
+    '''After 3 seconds the get call will unblock'''
+    print("I'll wait for you")
+    evt.wait()  # blocking
+    print("It's about time")
+
+def main():
+    gevent.joinall([
+        gevent.spawn(setter),
+        gevent.spawn(waiter),
+        gevent.spawn(waiter),
+        gevent.spawn(waiter),
+        gevent.spawn(waiter),
+        gevent.spawn(waiter)
+    ])
+
+if __name__ == '__main__': main()
 
 
 
@@ -792,13 +801,13 @@

Queues

Quitting time! Quitting time!

-

Queues can also block on either put or get as the need arises.

+

Queues can also block on either put or get as the need arises.

Each of the put and get operations has a non-blocking counterpart, put_nowait and get_nowait which will not block, but instead raise either gevent.queue.Empty or -gevent.queue.Full if the operation is not possible.

-

In the example below we have the boss running simultaneously to the +gevent.queue.Full in the operation is not possible.

+

In this example we have the boss running simultaneously to the workers and have a restriction on the Queue preventing it from containing more than three elements. This restriction means that the put operation will block until there is space on the queue. @@ -946,11 +955,11 @@

Groups and Pools


 Size of group 3
-Hello from Greenlet 10769424
+Hello from Greenlet 157878268
 Size of group 3
-Hello from Greenlet 10770544
+Hello from Greenlet 157878828
 Size of group 3
-Hello from Greenlet 10772304
+Hello from Greenlet 157878908
 Ordered
 ('task', 0)
 ('task', 1)
@@ -1243,7 +1252,7 @@ 

Actors

collection of independent Actors which have an inbox from which they receive messages from other Actors. The main loop inside the Actor iterates through its messages and takes action according to -its desired behavior.

+its desired behavior.

Gevent does not have a primitive Actor type, but we can define one very simply using a Queue inside of a subclassed Greenlet.

@@ -1306,7 +1315,7 @@ 

Gevent ZeroMQ

ZeroMQ is described by its authors as "a socket library that acts as a concurrency framework". It is a very powerful messaging layer for building concurrent and -distributed applications.

+distributed applications.

ZeroMQ provides a variety of socket primitives, the simplest of which being a Request-Response socket pair. A socket has two methods of interest send and recv, both of which are @@ -1400,7 +1409,7 @@

WSGI Servers

In earlier versions of gevent before 1.0.x, gevent used libevent instead of libev. Libevent included a fast HTTP server which was -used by gevent's wsgi server.

+used by gevent's wsgi server.

In gevent 1.0.x there is no http server included. Instead gevent.wsgi is now an alias for the pure Python server in gevent.pywsgi.

From 88054b3f58bc591fffbb65980ca62c3f2f229d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Marques=20Vieira?= Date: Fri, 19 Jul 2013 16:06:17 +0100 Subject: [PATCH 07/38] Fix timing typo --- index.html | 4 ++-- tutorial.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 8bc255b..7b62a72 100644 --- a/index.html +++ b/index.html @@ -277,8 +277,8 @@

Synchronous & Asynchronous Execu the async case is essentially random and that the total execution time in the async case is much less than the sync case. In fact the maximum time for the synchronous case to complete is when -each tasks pauses for 2 seconds resulting in a 20 seconds for the -whole queue. In the async case the maximum runtime is roughly 2 +each tasks pauses for 0.002 seconds resulting in a 0.02 seconds for the +whole queue. In the async case the maximum runtime is roughly 0.002 seconds since none of the tasks block the execution of the others.

In a more common use case, asynchronously fetching data from a server, diff --git a/tutorial.md b/tutorial.md index 56a3306..e82d3ae 100644 --- a/tutorial.md +++ b/tutorial.md @@ -179,8 +179,8 @@ The important fact to notice is that the order of execution in the async case is essentially random and that the total execution time in the async case is much less than the sync case. In fact the maximum time for the synchronous case to complete is when -each tasks pauses for 2 seconds resulting in a 20 seconds for the -whole queue. In the async case the maximum runtime is roughly 2 +each tasks pauses for 0.002 seconds resulting in a 0.02 seconds for the +whole queue. In the async case the maximum runtime is roughly 0.002 seconds since none of the tasks block the execution of the others. From 8a101433c5164abe2ab30d26c620f4ce429067b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Marques=20Vieira?= Date: Fri, 19 Jul 2013 16:27:04 +0100 Subject: [PATCH 08/38] Add parenthesis to all prints for consistency --- index.html | 38 +++++++++++++++++++------------------- tutorial.md | 38 +++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/index.html b/index.html index 7b62a72..f9612c9 100644 --- a/index.html +++ b/index.html @@ -297,7 +297,7 @@

Synchronous & Asynchronous Execu json_result = json.loads(result) datetime = json_result['datetime'] - print 'Process ', pid, datetime + print('Process', pid, datetime) return json_result['datetime'] def synchronous(): @@ -310,10 +310,10 @@

Synchronous & Asynchronous Execu threads.append(gevent.spawn(fetch, i)) gevent.joinall(threads) -print 'Synchronous:' +print('Synchronous:') synchronous() -print 'Asynchronous:' +print('Asynchronous:') asynchronous()

@@ -341,7 +341,7 @@

Determinism

run3 = [a for a in p.imap_unordered(echo, xrange(10))] run4 = [a for a in p.imap_unordered(echo, xrange(10))] -print( run1 == run2 == run3 == run4 ) +print(run1 == run2 == run3 == run4) # Deterministic Gevent Pool @@ -353,7 +353,7 @@

Determinism

run3 = [a for a in p.imap_unordered(echo, xrange(10))] run4 = [a for a in p.imap_unordered(echo, xrange(10))] -print( run1 == run2 == run3 == run4 ) +print(run1 == run2 == run3 == run4)
@@ -549,7 +549,7 @@

Timeouts

try: gevent.spawn(wait).join() except Timeout: - print 'Could not complete' + print('Could not complete') @@ -620,18 +620,18 @@

Monkeypatching

modify the standard library's socket library.

 import socket
-print( socket.socket )
+print(socket.socket)
 
-print "After monkey patch"
+print("After monkey patch")
 from gevent import monkey
 monkey.patch_socket()
-print( socket.socket )
+print(socket.socket)
 
 import select
-print select.select
+print(select.select)
 monkey.patch_select()
-print "After monkey patch"
-print( select.select )
+print("After monkey patch")
+print(select.select)
 
 
@@ -727,7 +727,7 @@

Events

After 3 seconds the get call will unblock after the setter puts a value into the AsyncResult. """ - print a.get() + print(a.get()) gevent.joinall([ gevent.spawn(setter), @@ -1161,14 +1161,14 @@

Subprocess

def cron(): while True: - print "cron" + print("cron") gevent.sleep(0.2) g = gevent.spawn(cron) sub = Popen(['sleep 1; uname'], stdout=PIPE, shell=True) out, err = sub.communicate() g.kill() -print out.rstrip() +print(out.rstrip())
@@ -1289,13 +1289,13 @@ 

Actors

class Pinger(Actor): def receive(self, message): - print message + print(message) pong.inbox.put('ping') gevent.sleep(0) class Ponger(Actor): def receive(self, message): - print message + print(message) ping.inbox.put('pong') gevent.sleep(0) @@ -1624,7 +1624,7 @@

Chat Server

def add(self, message): for user in self.users: - print user + print(user) user.queue.put_nowait(message) self.messages.append(message) @@ -1653,7 +1653,7 @@

Chat Server

active_room = rooms[room] active_room.subscribe(user) - print 'subscribe', active_room, user + print('subscribe', active_room, user) messages = active_room.backlog() diff --git a/tutorial.md b/tutorial.md index e82d3ae..f43d031 100644 --- a/tutorial.md +++ b/tutorial.md @@ -201,7 +201,7 @@ def fetch(pid): json_result = json.loads(result) datetime = json_result['datetime'] - print 'Process ', pid, datetime + print('Process', pid, datetime) return json_result['datetime'] def synchronous(): @@ -214,10 +214,10 @@ def asynchronous(): threads.append(gevent.spawn(fetch, i)) gevent.joinall(threads) -print 'Synchronous:' +print('Synchronous:') synchronous() -print 'Asynchronous:' +print('Asynchronous:') asynchronous()
@@ -247,7 +247,7 @@ run2 = [a for a in p.imap_unordered(echo, xrange(10))] run3 = [a for a in p.imap_unordered(echo, xrange(10))] run4 = [a for a in p.imap_unordered(echo, xrange(10))] -print( run1 == run2 == run3 == run4 ) +print(run1 == run2 == run3 == run4) # Deterministic Gevent Pool @@ -259,7 +259,7 @@ run2 = [a for a in p.imap_unordered(echo, xrange(10))] run3 = [a for a in p.imap_unordered(echo, xrange(10))] run4 = [a for a in p.imap_unordered(echo, xrange(10))] -print( run1 == run2 == run3 == run4 ) +print(run1 == run2 == run3 == run4) @@ -451,7 +451,7 @@ def wait(): try: gevent.spawn(wait).join() except Timeout: - print 'Could not complete' + print('Could not complete') @@ -521,18 +521,18 @@ modify the standard library's socket library.
 import socket
-print( socket.socket )
+print(socket.socket)
 
-print "After monkey patch"
+print("After monkey patch")
 from gevent import monkey
 monkey.patch_socket()
-print( socket.socket )
+print(socket.socket)
 
 import select
-print select.select
+print(select.select)
 monkey.patch_select()
-print "After monkey patch"
-print( select.select )
+print("After monkey patch")
+print(select.select)
 
 
@@ -637,7 +637,7 @@ def waiter(): After 3 seconds the get call will unblock after the setter puts a value into the AsyncResult. """ - print a.get() + print(a.get()) gevent.joinall([ gevent.spawn(setter), @@ -990,14 +990,14 @@ from gevent.subprocess import Popen, PIPE def cron(): while True: - print "cron" + print("cron") gevent.sleep(0.2) g = gevent.spawn(cron) sub = Popen(['sleep 1; uname'], stdout=PIPE, shell=True) out, err = sub.communicate() g.kill() -print out.rstrip() +print(out.rstrip())
@@ -1125,13 +1125,13 @@ from gevent import Greenlet
 
 class Pinger(Actor):
     def receive(self, message):
-        print message
+        print(message)
         pong.inbox.put('ping')
         gevent.sleep(0)
 
 class Ponger(Actor):
     def receive(self, message):
-        print message
+        print(message)
         ping.inbox.put('pong')
         gevent.sleep(0)
 
@@ -1466,7 +1466,7 @@ class Room(object):
 
     def add(self, message):
         for user in self.users:
-            print user
+            print(user)
             user.queue.put_nowait(message)
         self.messages.append(message)
 
@@ -1495,7 +1495,7 @@ def join(room, uid):
 
     active_room = rooms[room]
     active_room.subscribe(user)
-    print 'subscribe', active_room, user
+    print('subscribe', active_room, user)
 
     messages = active_room.backlog()
 

From ff3deb4e8215f7aea95dfd3c101135dbc8245dcf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Marques=20Vieira?=
 
Date: Fri, 19 Jul 2013 16:35:20 +0100
Subject: [PATCH 09/38] Avoid multiple arguments in prints so they all work in
 Python 2 and 3

---
 index.html  | 70 ++++++++++++++++++++++++++---------------------------
 tutorial.md | 24 +++++++++---------
 2 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/index.html b/index.html
index f9612c9..9fc5283 100644
--- a/index.html
+++ b/index.html
@@ -177,18 +177,18 @@ 

Synchronous & Asynchronous Execu def gr1(): # Busy waits for a second, but we don't want to stick around... - print('Started Polling: ', tic()) + print('Started Polling: %s' % tic()) select.select([], [], [], 2) - print('Ended Polling: ', tic()) + print('Ended Polling: %s' % tic()) def gr2(): # Busy waits for a second, but we don't want to stick around... - print('Started Polling: ', tic()) + print('Started Polling: %s' % tic()) select.select([], [], [], 2) - print('Ended Polling: ', tic()) + print('Ended Polling: %s' % tic()) def gr3(): - print("Hey lets do some stuff while the greenlets poll, ", tic()) + print("Hey lets do some stuff while the greenlets poll, %s" % tic()) gevent.sleep(1) gevent.joinall([ @@ -200,11 +200,11 @@

Synchronous & Asynchronous Execu


-Started Polling:  at 0.0 seconds
-Started Polling:  at 0.0 seconds
-Hey lets do some stuff while the greenlets poll,  at 0.0 seconds
-Ended Polling:  at 2.0 seconds
-Ended Polling:  at 2.0 seconds
+Started Polling: at 0.0 seconds
+Started Polling: at 0.0 seconds
+Hey lets do some stuff while the greenlets poll, at 0.0 seconds
+Ended Polling: at 2.0 seconds
+Ended Polling: at 2.0 seconds
 

Another somewhat synthetic example defines a task function which is non-deterministic @@ -221,7 +221,7 @@

Synchronous & Asynchronous Execu Some non-deterministic task """ gevent.sleep(random.randint(0,2)*0.001) - print('Task', pid, 'done') + print('Task %s done' % pid) def synchronous(): for i in range(1,10): @@ -297,7 +297,7 @@

Synchronous & Asynchronous Execu json_result = json.loads(result) datetime = json_result['datetime'] - print('Process', pid, datetime) + print('Process %s: %s' % (pid, datetime)) return json_result['datetime'] def synchronous(): @@ -929,7 +929,7 @@

Groups and Pools

group = Group() def hello_from(n): - print('Size of group', len(group)) + print('Size of group %s' % len(group)) print('Hello from Greenlet %s' % id(getcurrent())) group.map(hello_from, xrange(3)) @@ -980,7 +980,7 @@

Groups and Pools

pool = Pool(2) def hello_from(n): - print('Size of pool', len(pool)) + print('Size of pool %s' % len(pool)) pool.map(hello_from, xrange(3))
@@ -1338,7 +1338,7 @@

Gevent ZeroMQ

for request in range(1,10): server_socket.send("Hello") - print('Switched to Server for ', request) + print('Switched to Server for %s' % request) # Implicit context switch occurs here server_socket.recv() @@ -1349,7 +1349,7 @@

Gevent ZeroMQ

for request in range(1,10): client_socket.recv() - print('Switched to Client for ', request) + print('Switched to Client for %s' % request) # Implicit context switch occurs here client_socket.send("World") @@ -1362,24 +1362,24 @@

Gevent ZeroMQ


-Switched to Server for  1
-Switched to Client for  1
-Switched to Server for  2
-Switched to Client for  2
-Switched to Server for  3
-Switched to Client for  3
-Switched to Server for  4
-Switched to Client for  4
-Switched to Server for  5
-Switched to Client for  5
-Switched to Server for  6
-Switched to Client for  6
-Switched to Server for  7
-Switched to Client for  7
-Switched to Server for  8
-Switched to Client for  8
-Switched to Server for  9
-Switched to Client for  9
+Switched to Server for 1
+Switched to Client for 1
+Switched to Server for 2
+Switched to Client for 2
+Switched to Server for 3
+Switched to Client for 3
+Switched to Server for 4
+Switched to Client for 4
+Switched to Server for 5
+Switched to Client for 5
+Switched to Server for 6
+Switched to Client for 6
+Switched to Server for 7
+Switched to Client for 7
+Switched to Server for 8
+Switched to Client for 8
+Switched to Server for 9
+Switched to Client for 9
 

Simple Servers

@@ -1653,7 +1653,7 @@ 

Chat Server

active_room = rooms[room] active_room.subscribe(user) - print('subscribe', active_room, user) + print('subscribe %s %s' % (active_room, user)) messages = active_room.backlog() diff --git a/tutorial.md b/tutorial.md index f43d031..290242c 100644 --- a/tutorial.md +++ b/tutorial.md @@ -106,18 +106,18 @@ tic = lambda: 'at %1.1f seconds' % (time.time() - start) def gr1(): # Busy waits for a second, but we don't want to stick around... - print('Started Polling: ', tic()) + print('Started Polling: %s' % tic()) select.select([], [], [], 2) - print('Ended Polling: ', tic()) + print('Ended Polling: %s' % tic()) def gr2(): # Busy waits for a second, but we don't want to stick around... - print('Started Polling: ', tic()) + print('Started Polling: %s' % tic()) select.select([], [], [], 2) - print('Ended Polling: ', tic()) + print('Ended Polling: %s' % tic()) def gr3(): - print("Hey lets do some stuff while the greenlets poll, ", tic()) + print("Hey lets do some stuff while the greenlets poll, %s" % tic()) gevent.sleep(1) gevent.joinall([ @@ -144,7 +144,7 @@ def task(pid): Some non-deterministic task """ gevent.sleep(random.randint(0,2)*0.001) - print('Task', pid, 'done') + print('Task %s done' % pid) def synchronous(): for i in range(1,10): @@ -201,7 +201,7 @@ def fetch(pid): json_result = json.loads(result) datetime = json_result['datetime'] - print('Process', pid, datetime) + print('Process %s: %s' % (pid, datetime)) return json_result['datetime'] def synchronous(): @@ -783,7 +783,7 @@ from gevent.pool import Group group = Group() def hello_from(n): - print('Size of group', len(group)) + print('Size of group %s' % len(group)) print('Hello from Greenlet %s' % id(getcurrent())) group.map(hello_from, xrange(3)) @@ -820,7 +820,7 @@ from gevent.pool import Pool pool = Pool(2) def hello_from(n): - print('Size of pool', len(pool)) + print('Size of pool %s' % len(pool)) pool.map(hello_from, xrange(3)) ]]] @@ -1178,7 +1178,7 @@ def server(): for request in range(1,10): server_socket.send("Hello") - print('Switched to Server for ', request) + print('Switched to Server for %s' % request) # Implicit context switch occurs here server_socket.recv() @@ -1189,7 +1189,7 @@ def client(): for request in range(1,10): client_socket.recv() - print('Switched to Client for ', request) + print('Switched to Client for %s' % request) # Implicit context switch occurs here client_socket.send("World") @@ -1495,7 +1495,7 @@ def join(room, uid): active_room = rooms[room] active_room.subscribe(user) - print('subscribe', active_room, user) + print('subscribe %s %s' % (active_room, user)) messages = active_room.backlog() From f1f614c92ad3d298390cb075a5f980578f7a9230 Mon Sep 17 00:00:00 2001 From: David Xia Date: Fri, 23 Aug 2013 00:30:28 -0400 Subject: [PATCH 10/38] Fixed some typos --- tutorial.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tutorial.md b/tutorial.md index 290242c..b4f327c 100644 --- a/tutorial.md +++ b/tutorial.md @@ -614,7 +614,7 @@ if __name__ == '__main__': main()
-A extension of the Event object is the AsyncResult which +An extension of the Event object is the AsyncResult which allows you to send a value along with the wakeup call. This is sometimes called a future or a deferred, since it holds a reference to a future value that can be set on an arbitrary time @@ -691,7 +691,7 @@ Each of the ``put`` and ``get`` operations has a non-blocking counterpart, ``put_nowait`` and ``get_nowait`` which will not block, but instead raise either ``gevent.queue.Empty`` or -``gevent.queue.Full`` in the operation is not possible. +``gevent.queue.Full`` if the operation is not possible. In this example we have the boss running simultaneously to the workers and have a restriction on the Queue preventing it from containing @@ -929,10 +929,10 @@ gevent.joinall([g1, g2]) ]]] [[[end]]] -Many web framework thats integrate with gevent store HTTP session -objects inside of gevent thread locals. For example using the +Many web frameworks that use gevent store HTTP session +objects inside gevent thread locals. For example, using the Werkzeug utility library and its proxy object we can create -Flask style request objects. +Flask-style request objects.
 from gevent.local import local

From 9c4c172104962bc48c1da8cb37cec57a807e4fb9 Mon Sep 17 00:00:00 2001
From: satoru 
Date: Sat, 28 Sep 2013 20:47:59 +0800
Subject: [PATCH 11/38] fix syntax

---
 index.html | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/index.html b/index.html
index 9fc5283..dbd335f 100644
--- a/index.html
+++ b/index.html
@@ -741,8 +741,8 @@ 

Queues

Queues are ordered sets of data that have the usual put / get operations but are written in a way such that they can be safely manipulated across Greenlets.

-

For example if one Greenlet grabs an item off of the queue, the -same item will not grabbed by another Greenlet executing +

For example, if one Greenlet grabs an item off of the queue, the +same item will not be grabbed by another Greenlet executing simultaneously.


 import gevent
@@ -1686,4 +1686,4 @@ 

Chat Server

- \ No newline at end of file + From 4fdf4ab333f92ab7bddd8289c33257b1f9ea2dcd Mon Sep 17 00:00:00 2001 From: satoru Date: Sun, 29 Sep 2013 17:02:52 +0800 Subject: [PATCH 12/38] fix NameError in example --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index dbd335f..6668b82 100644 --- a/index.html +++ b/index.html @@ -1263,7 +1263,7 @@

Actors

def __init__(self): self.inbox = Queue() - Greenlet.__init__(self) + gevent.Greenlet.__init__(self) def receive(self, message): """ From 6d0ba17d4c4f6140a50459dce7bb396d18e8c94f Mon Sep 17 00:00:00 2001 From: James Summerfield Date: Fri, 4 Oct 2013 21:11:00 +0100 Subject: [PATCH 13/38] Update tutorial.md Language fix --- tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial.md b/tutorial.md index b4f327c..ed0bad6 100644 --- a/tutorial.md +++ b/tutorial.md @@ -57,7 +57,7 @@ into a collection of subtasks which are scheduled to run simultaneously or *asynchronously*, instead of one at a time or *synchronously*. A switch between the two subtasks is known as a *context switch*. -A context switch in gevent is done through *yielding*. In this case +A context switch in gevent is done through *yielding*. In this example we have two contexts which yield to each other through invoking ``gevent.sleep(0)``. From 8656dbd87690c65a7f897175f6622f106695fe56 Mon Sep 17 00:00:00 2001 From: Adam Szkoda Date: Sun, 13 Oct 2013 12:12:34 +0200 Subject: [PATCH 14/38] Added missing word --- tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial.md b/tutorial.md index b4f327c..f65dd52 100644 --- a/tutorial.md +++ b/tutorial.md @@ -700,7 +700,7 @@ operation will block until there is space on the queue. Conversely the ``get`` operation will block if there are no elements on the queue to fetch, it also takes a timeout argument to allow for the queue to exit with the exception -``gevent.queue.Empty`` if no work can found within the +``gevent.queue.Empty`` if no work can be found within the time frame of the Timeout. [[[cog From 048f0528dc51e062e31dfb569e3bac4ab35ce5c6 Mon Sep 17 00:00:00 2001 From: Adam Szkoda Date: Sun, 13 Oct 2013 12:13:12 +0200 Subject: [PATCH 15/38] More descriptive function parameter name --- tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial.md b/tutorial.md index f65dd52..569a5af 100644 --- a/tutorial.md +++ b/tutorial.md @@ -709,11 +709,11 @@ from gevent.queue import Queue, Empty tasks = Queue(maxsize=3) -def worker(n): +def worker(name): try: while True: task = tasks.get(timeout=1) # decrements queue size by 1 - print('Worker %s got task %s' % (n, task)) + print('Worker %s got task %s' % (name, task)) gevent.sleep(0) except Empty: print('Quitting time!') From b498945873e128414f0f0bbffe605bc66ef1555e Mon Sep 17 00:00:00 2001 From: Roy Smith Date: Sat, 28 Dec 2013 10:36:26 -0500 Subject: [PATCH 16/38] Fix typo --- tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial.md b/tutorial.md index 8a8578b..a179b40 100644 --- a/tutorial.md +++ b/tutorial.md @@ -860,7 +860,7 @@ class SocketPool(object): A semaphore is a low level synchronization primitive that allows greenlets to coordinate and limit concurrent access or execution. A semaphore exposes two methods, ``acquire`` and ``release`` The -difference between the number of times and a semaphore has been +difference between the number of times a semaphore has been acquired and released is called the bound of the semaphore. If a semaphore bound reaches 0 it will block until another greenlet releases its acquisition. From a98db6084a85fcb2c4b7bbcbf1306d4bedb2b88d Mon Sep 17 00:00:00 2001 From: Jianbin Wei Date: Wed, 12 Feb 2014 10:06:43 -0800 Subject: [PATCH 17/38] fix grammar error --- tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial.md b/tutorial.md index a179b40..03cdbab 100644 --- a/tutorial.md +++ b/tutorial.md @@ -654,7 +654,7 @@ operations but are written in a way such that they can be safely manipulated across Greenlets. For example if one Greenlet grabs an item off of the queue, the -same item will not grabbed by another Greenlet executing +same item will not be grabbed by another Greenlet executing simultaneously. [[[cog From 23b0d66de99f92a840426ef55b798bb522c9108c Mon Sep 17 00:00:00 2001 From: Anton Larkin Date: Mon, 24 Mar 2014 15:50:10 +0300 Subject: [PATCH 18/38] Fix typo --- tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial.md b/tutorial.md index 03cdbab..78a4aac 100644 --- a/tutorial.md +++ b/tutorial.md @@ -1426,7 +1426,7 @@ HTML Page: ## Chat Server The final motivating example, a realtime chat room. This example -requires Flask ( but not neccesarily so, you could use Django, +requires Flask ( but not necessarily so, you could use Django, Pyramid, etc ). The corresponding Javascript and HTML files can be found here. From b49cf38e67cd7e36c615dd1dac009ac111b43406 Mon Sep 17 00:00:00 2001 From: Matias Herranz Date: Thu, 3 Apr 2014 13:31:41 -0300 Subject: [PATCH 19/38] Tutorial fixes. --- tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial.md b/tutorial.md index 78a4aac..93fad8b 100644 --- a/tutorial.md +++ b/tutorial.md @@ -393,7 +393,7 @@ print(loser.ready()) # True print(winner.successful()) # True print(loser.successful()) # False -# The exception raised in fail, will not propogate outside the +# The exception raised in fail, will not propagate outside the # greenlet. A stack trace will be printed to stdout but it # will not unwind the stack of the parent. @@ -424,7 +424,7 @@ def run_forever(): gevent.sleep(1000) if __name__ == '__main__': - gevent.signal(signal.SIGQUIT, gevent.shutdown) + gevent.signal(signal.SIGQUIT, gevent.kill) thread = gevent.spawn(run_forever) thread.join()
From 540c77cf8af7c2eff72657b4e1135d363f6770dc Mon Sep 17 00:00:00 2001 From: Scott Greenwald Date: Sun, 19 Oct 2014 17:29:14 -0400 Subject: [PATCH 20/38] use zmq.green instead of gevent_zeromq. Fixes #40 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PyZMQ ≥ 2.2.0.1 ships with a gevent compatible API as zmq.green. Besides the fact that using the new, integrated lib is generally a good idea, gevent_zeromq throws an AttributeError when used alongside the newer pyzmq. --- index.html | 4 ++-- requirements.txt | 2 +- tutorial.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 6668b82..3180e17 100644 --- a/index.html +++ b/index.html @@ -1325,9 +1325,9 @@

Gevent ZeroMQ

manner. You can install gevent-zeromq from PyPi via: pip install gevent-zeromq


-# Note: Remember to ``pip install pyzmq gevent_zeromq``
+# Note: Remember to ``pip install pyzmq``
 import gevent
-from gevent_zeromq import zmq
+import zmq.green as zmq
 
 # Global Context
 context = zmq.Context()
diff --git a/requirements.txt b/requirements.txt
index 9a10e26..b17eeac 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,4 +2,4 @@ Markdown==2.1.1
 cogapp==2.3
 Jinja2==2.6
 gevent
-gevent-zeromq
+pyzmq
diff --git a/tutorial.md b/tutorial.md
index 93fad8b..7dd6746 100644
--- a/tutorial.md
+++ b/tutorial.md
@@ -1165,9 +1165,9 @@ manner.  You can install gevent-zeromq from PyPi via:  ``pip install
 gevent-zeromq``
 
 [[[cog
-# Note: Remember to ``pip install pyzmq gevent_zeromq``
+# Note: Remember to ``pip install pyzmq``
 import gevent
-from gevent_zeromq import zmq
+import zmq.green as zmq
 
 # Global Context
 context = zmq.Context()

From 861de520af375daa40edba160fd6c651a1269fac Mon Sep 17 00:00:00 2001
From: Pietro Bertera 
Date: Fri, 19 Dec 2014 20:17:02 +0100
Subject: [PATCH 21/38] Update requirements.txt

gevent-zeromq is now named pyzmq
---
 requirements.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/requirements.txt b/requirements.txt
index 9a10e26..b17eeac 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,4 +2,4 @@ Markdown==2.1.1
 cogapp==2.3
 Jinja2==2.6
 gevent
-gevent-zeromq
+pyzmq

From 9e7685e76f17d61f83692e1dfff701e190a0bfbc Mon Sep 17 00:00:00 2001
From: Pietro Bertera 
Date: Fri, 19 Dec 2014 20:19:48 +0100
Subject: [PATCH 22/38] Added Italian translation link

---
 tutorial.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tutorial.md b/tutorial.md
index 93fad8b..a02382b 100644
--- a/tutorial.md
+++ b/tutorial.md
@@ -32,7 +32,7 @@ Have something to add? See a typo? Fork and issue a
 pull request [Github](https://github.com/sdiehl/gevent-tutorial).
 Any and all contributions are welcome.
 
-This page is also [available in Japanese](http://methane.github.com/gevent-tutorial-ja).
+This page is also [available in Japanese](http://methane.github.com/gevent-tutorial-ja) and [Italian](http://pbertera.github.io/gevent-tutorial-it/).
 
 # Core
 

From 195cae5ac4a37fd259b72eca50f06cfa9053744b Mon Sep 17 00:00:00 2001
From: Stephen Diehl 
Date: Fri, 19 Dec 2014 16:59:26 -0600
Subject: [PATCH 23/38] rebuild html with italian translation

---
 index.html | 54 +++++++++++++++++++++++++++---------------------------
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/index.html b/index.html
index 6668b82..2f32688 100644
--- a/index.html
+++ b/index.html
@@ -108,7 +108,7 @@ 

Contributors

Have something to add? See a typo? Fork and issue a pull request Github. Any and all contributions are welcome.

-

This page is also available in Japanese.

+

This page is also available in Japanese and Italian.

Core

Greenlets

The primary pattern used in gevent is the Greenlet, a @@ -127,7 +127,7 @@

Synchronous & Asynchronous Execu into a collection of subtasks which are scheduled to run simultaneously or asynchronously, instead of one at a time or synchronously. A switch between the two subtasks is known as a context switch.

-

A context switch in gevent is done through yielding. In this case +

A context switch in gevent is done through yielding. In this example we have two contexts which yield to each other through invoking gevent.sleep(0).


@@ -251,16 +251,16 @@ 

Synchronous & Asynchronous Execu Task 8 done Task 9 done Asynchronous: -Task 3 done -Task 7 done Task 2 done -Task 6 done Task 5 done -Task 4 done -Task 0 done -Task 1 done -Task 8 done +Task 3 done Task 9 done +Task 8 done +Task 6 done +Task 1 done +Task 7 done +Task 0 done +Task 4 done

In the synchronous case all the tasks are run sequentially, which results in the main programming blocking ( @@ -485,7 +485,7 @@

Greenlet State

print(winner.successful()) # True print(loser.successful()) # False -# The exception raised in fail, will not propogate outside the +# The exception raised in fail, will not propagate outside the # greenlet. A stack trace will be printed to stdout but it # will not unwind the stack of the parent. @@ -524,7 +524,7 @@

Program Shutdown

gevent.sleep(1000) if __name__ == '__main__': - gevent.signal(signal.SIGQUIT, gevent.shutdown) + gevent.signal(signal.SIGQUIT, gevent.kill) thread = gevent.spawn(run_forever) thread.join()
@@ -705,7 +705,7 @@

Events

-

A extension of the Event object is the AsyncResult which +

An extension of the Event object is the AsyncResult which allows you to send a value along with the wakeup call. This is sometimes called a future or a deferred, since it holds a reference to a future value that can be set on an arbitrary time @@ -741,7 +741,7 @@

Queues

Queues are ordered sets of data that have the usual put / get operations but are written in a way such that they can be safely manipulated across Greenlets.

-

For example, if one Greenlet grabs an item off of the queue, the +

For example if one Greenlet grabs an item off of the queue, the same item will not be grabbed by another Greenlet executing simultaneously.


@@ -806,7 +806,7 @@ 

Queues

counterpart, put_nowait and get_nowait which will not block, but instead raise either gevent.queue.Empty or -gevent.queue.Full in the operation is not possible.

+gevent.queue.Full if the operation is not possible.

In this example we have the boss running simultaneously to the workers and have a restriction on the Queue preventing it from containing more than three elements. This restriction means that the put @@ -814,7 +814,7 @@

Queues

Conversely the get operation will block if there are no elements on the queue to fetch, it also takes a timeout argument to allow for the queue to exit with the exception -gevent.queue.Empty if no work can found within the +gevent.queue.Empty if no work can be found within the time frame of the Timeout.


 import gevent
@@ -822,11 +822,11 @@ 

Queues

tasks = Queue(maxsize=3) -def worker(n): +def worker(name): try: while True: task = tasks.get(timeout=1) # decrements queue size by 1 - print('Worker %s got task %s' % (n, task)) + print('Worker %s got task %s' % (name, task)) gevent.sleep(0) except Empty: print('Quitting time!') @@ -955,11 +955,11 @@

Groups and Pools


 Size of group 3
-Hello from Greenlet 157878268
+Hello from Greenlet 36360912
 Size of group 3
-Hello from Greenlet 157878828
+Hello from Greenlet 36361392
 Size of group 3
-Hello from Greenlet 157878908
+Hello from Greenlet 36362352
 Ordered
 ('task', 0)
 ('task', 1)
@@ -1023,7 +1023,7 @@ 

Locks and Semaphores

A semaphore is a low level synchronization primitive that allows greenlets to coordinate and limit concurrent access or execution. A semaphore exposes two methods, acquire and release The -difference between the number of times and a semaphore has been +difference between the number of times a semaphore has been acquired and released is called the bound of the semaphore. If a semaphore bound reaches 0 it will block until another greenlet releases its acquisition.

@@ -1105,10 +1105,10 @@

Thread Locals

2 x is not local to f2

-

Many web framework thats integrate with gevent store HTTP session -objects inside of gevent thread locals. For example using the +

Many web frameworks that use gevent store HTTP session +objects inside gevent thread locals. For example, using the Werkzeug utility library and its proxy object we can create -Flask style request objects.

+Flask-style request objects.

 from gevent.local import local
 from werkzeug.local import LocalProxy
@@ -1263,7 +1263,7 @@ 

Actors

def __init__(self): self.inbox = Queue() - gevent.Greenlet.__init__(self) + Greenlet.__init__(self) def receive(self, message): """ @@ -1586,7 +1586,7 @@

Websockets

Chat Server

The final motivating example, a realtime chat room. This example -requires Flask ( but not neccesarily so, you could use Django, +requires Flask ( but not necessarily so, you could use Django, Pyramid, etc ). The corresponding Javascript and HTML files can be found here.

@@ -1686,4 +1686,4 @@ 

Chat Server

- + \ No newline at end of file From b0418f75805669c7bf1805d0456995e95cc0885c Mon Sep 17 00:00:00 2001 From: Jan-Philip Gehrcke Date: Tue, 16 Jun 2015 16:39:32 +0200 Subject: [PATCH 24/38] Update list of contributors This updates the list of contributors, based on the current state of the git repository. I have extracted the chronological order of contributions from the git log with a little helper tool, and subsequently verified/created the list of names and websites, manually. --- index.html | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 2f32688..2aad13b 100644 --- a/index.html +++ b/index.html @@ -101,7 +101,28 @@

Contributors

youngsterxyf Eddie Hebert Alexis Metaireau -Daniel Velkov

+Daniel Velkov +Sean Wang +Inada Naoki +Balthazar Rouberol +Glen Baker +Jan-Philip Gehrcke +Matthijs van der Vleuten +Simon Hayward +Alexander James Phillips +Ramiro Morales +Philip Damra +Francisco José Marques Vieira +David Xia +satoru +James Summerfield +Adam Szkoda +Roy Smith +Jianbin Wei +Anton Larkin +Matias Herranz +Pietro Bertera +

Also thanks to Denis Bilenko for writing gevent and guidance in constructing this tutorial.

This is a collaborative document published under MIT license. @@ -1686,4 +1707,4 @@

Chat Server

- \ No newline at end of file + From b4bccf1bdd982e06bb807a2a117165ce4f4c8ddc Mon Sep 17 00:00:00 2001 From: Jan-Philip Gehrcke Date: Tue, 16 Jun 2015 16:54:31 +0200 Subject: [PATCH 25/38] Update list of contributors in tutorial.md. --- tutorial.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tutorial.md b/tutorial.md index a02382b..77c5475 100644 --- a/tutorial.md +++ b/tutorial.md @@ -23,6 +23,26 @@ In chronological order of contribution: [Eddie Hebert](https://github.com/ehebert) [Alexis Metaireau](http://notmyidea.org) [Daniel Velkov](https://github.com/djv) +[Sean Wang](https://github.com/sww) +[Inada Naoki](https://github.com/methane) +[Balthazar Rouberol](https://github.com/brouberol) +[Glen Baker](https://github.com/iepathos) +[Jan-Philip Gehrcke](https://gehrcke.de) +[Matthijs van der Vleuten](https://github.com/zr40) +[Simon Hayward](http://simonsblog.co.uk) +[Alexander James Phillips](https://github.com/AJamesPhillips) +[Ramiro Morales](https://github.com/ramiro) +[Philip Damra](https://github.com/djheru) +[Francisco José Marques Vieira](https://github.com/fvieira) +[David Xia](https://www.davidxia.com) +[satoru](https://github.com/satoru) +[James Summerfield](https://github.com/jsummerfield) +[Adam Szkoda](https://github.com/adaszko) +[Roy Smith](https://github.com/roysmith) +[Jianbin Wei](https://github.com/jianbin-netskope) +[Anton Larkin](https://github.com/ToxicWar) +[Matias Herranz](https://github.com/matiasherranz-santex) +[Pietro Bertera](http://www.bertera.it) Also thanks to Denis Bilenko for writing gevent and guidance in constructing this tutorial. From 1646b27a94180c1e797d8b8c84b23ac7d43a2859 Mon Sep 17 00:00:00 2001 From: Asad Dhamani Date: Wed, 28 Oct 2015 11:27:14 -0400 Subject: [PATCH 26/38] Changes to reflect pyzmq gevent_zeromq merge --- index.html | 55 ++++++++++++++++++++++++++--------------------------- tutorial.md | 4 ++-- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/index.html b/index.html index 2aad13b..d8e707d 100644 --- a/index.html +++ b/index.html @@ -121,8 +121,7 @@

Contributors

Jianbin Wei Anton Larkin Matias Herranz -Pietro Bertera -

+Pietro Bertera

Also thanks to Denis Bilenko for writing gevent and guidance in constructing this tutorial.

This is a collaborative document published under MIT license. @@ -272,16 +271,16 @@

Synchronous & Asynchronous Execu Task 8 done Task 9 done Asynchronous: +Task 1 done +Task 9 done +Task 0 done Task 2 done -Task 5 done Task 3 done -Task 9 done -Task 8 done +Task 5 done Task 6 done -Task 1 done -Task 7 done -Task 0 done +Task 8 done Task 4 done +Task 7 done

In the synchronous case all the tasks are run sequentially, which results in the main programming blocking ( @@ -798,26 +797,26 @@

Queues

Worker john got task 2 Worker nancy got task 3 Worker steve got task 4 -Worker nancy got task 5 -Worker john got task 6 +Worker john got task 5 +Worker nancy got task 6 Worker steve got task 7 Worker john got task 8 Worker nancy got task 9 Worker steve got task 10 -Worker nancy got task 11 -Worker john got task 12 +Worker john got task 11 +Worker nancy got task 12 Worker steve got task 13 Worker john got task 14 Worker nancy got task 15 Worker steve got task 16 -Worker nancy got task 17 -Worker john got task 18 +Worker john got task 17 +Worker nancy got task 18 Worker steve got task 19 Worker john got task 20 Worker nancy got task 21 Worker steve got task 22 -Worker nancy got task 23 -Worker john got task 24 +Worker john got task 23 +Worker nancy got task 24 Quitting time! Quitting time! Quitting time! @@ -880,21 +879,21 @@

Queues

Worker john got task 2 Worker bob got task 3 Worker steve got task 4 -Worker bob got task 5 -Worker john got task 6 +Worker john got task 5 +Worker bob got task 6 Assigned all work in iteration 1 Worker steve got task 7 Worker john got task 8 Worker bob got task 9 Worker steve got task 10 -Worker bob got task 11 -Worker john got task 12 +Worker john got task 11 +Worker bob got task 12 Worker steve got task 13 Worker john got task 14 Worker bob got task 15 Worker steve got task 16 -Worker bob got task 17 -Worker john got task 18 +Worker john got task 17 +Worker bob got task 18 Assigned all work in iteration 2 Worker steve got task 19 Quitting time! @@ -976,11 +975,11 @@

Groups and Pools


 Size of group 3
-Hello from Greenlet 36360912
+Hello from Greenlet 140210785595632
 Size of group 3
-Hello from Greenlet 36361392
+Hello from Greenlet 140210785596752
 Size of group 3
-Hello from Greenlet 36362352
+Hello from Greenlet 140210785596272
 Ordered
 ('task', 0)
 ('task', 1)
@@ -1346,9 +1345,9 @@ 

Gevent ZeroMQ

manner. You can install gevent-zeromq from PyPi via: pip install gevent-zeromq


-# Note: Remember to ``pip install pyzmq gevent_zeromq``
+# Note: Remember to ``pip install pyzmq``
 import gevent
-from gevent_zeromq import zmq
+import zmq.green as zmq
 
 # Global Context
 context = zmq.Context()
@@ -1707,4 +1706,4 @@ 

Chat Server

- + \ No newline at end of file diff --git a/tutorial.md b/tutorial.md index 77c5475..c98ca95 100644 --- a/tutorial.md +++ b/tutorial.md @@ -1185,9 +1185,9 @@ manner. You can install gevent-zeromq from PyPi via: ``pip install gevent-zeromq`` [[[cog -# Note: Remember to ``pip install pyzmq gevent_zeromq`` +# Note: Remember to ``pip install pyzmq`` import gevent -from gevent_zeromq import zmq +import zmq.green as zmq # Global Context context = zmq.Context() From bc530592c7339ef601a448df6e9da9f6045e20c5 Mon Sep 17 00:00:00 2001 From: Asad Dhamani Date: Wed, 28 Oct 2015 11:34:05 -0400 Subject: [PATCH 27/38] Change URL for json-time service --- index.html | 18 +++++++++--------- tutorial.md | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/index.html b/index.html index d8e707d..4437853 100644 --- a/index.html +++ b/index.html @@ -271,16 +271,16 @@

Synchronous & Asynchronous Execu Task 8 done Task 9 done Asynchronous: -Task 1 done +Task 7 done +Task 4 done +Task 5 done +Task 8 done Task 9 done Task 0 done +Task 1 done Task 2 done Task 3 done -Task 5 done Task 6 done -Task 8 done -Task 4 done -Task 7 done

In the synchronous case all the tasks are run sequentially, which results in the main programming blocking ( @@ -312,7 +312,7 @@

Synchronous & Asynchronous Execu import simplejson as json def fetch(pid): - response = urllib2.urlopen('http://json-time.appspot.com/time.json') + response = urllib2.urlopen('http://jsontime.herokuapp.com/') result = response.read() json_result = json.loads(result) datetime = json_result['datetime'] @@ -975,11 +975,11 @@

Groups and Pools


 Size of group 3
-Hello from Greenlet 140210785595632
+Hello from Greenlet 139643393732848
 Size of group 3
-Hello from Greenlet 140210785596752
+Hello from Greenlet 139643393733968
 Size of group 3
-Hello from Greenlet 140210785596272
+Hello from Greenlet 139643393733488
 Ordered
 ('task', 0)
 ('task', 1)
diff --git a/tutorial.md b/tutorial.md
index c98ca95..ea07313 100644
--- a/tutorial.md
+++ b/tutorial.md
@@ -216,7 +216,7 @@ import urllib2
 import simplejson as json
 
 def fetch(pid):
-    response = urllib2.urlopen('http://json-time.appspot.com/time.json')
+    response = urllib2.urlopen('http://jsontime.herokuapp.com/')
     result = response.read()
     json_result = json.loads(result)
     datetime = json_result['datetime']

From abd1bccf950adf1beb45596e7619b56c3f12464e Mon Sep 17 00:00:00 2001
From: Lu Dang 
Date: Sun, 29 Nov 2015 22:15:01 +0800
Subject: [PATCH 28/38] fix outdated zeromq text and code

---
 index.html  | 67 ++++++++++++++++++++++++++++-------------------------
 tutorial.md | 11 ++++-----
 2 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/index.html b/index.html
index 2aad13b..77882cc 100644
--- a/index.html
+++ b/index.html
@@ -121,8 +121,7 @@ 

Contributors

Jianbin Wei Anton Larkin Matias Herranz -Pietro Bertera -

+Pietro Bertera

Also thanks to Denis Bilenko for writing gevent and guidance in constructing this tutorial.

This is a collaborative document published under MIT license. @@ -272,16 +271,16 @@

Synchronous & Asynchronous Execu Task 8 done Task 9 done Asynchronous: -Task 2 done +Task 1 done Task 5 done -Task 3 done -Task 9 done -Task 8 done Task 6 done -Task 1 done +Task 2 done +Task 4 done Task 7 done +Task 8 done +Task 9 done Task 0 done -Task 4 done +Task 3 done

In the synchronous case all the tasks are run sequentially, which results in the main programming blocking ( @@ -696,6 +695,7 @@

Events

Illustrates the use of events ''' + evt = Event() def setter(): @@ -705,6 +705,7 @@

Events

print("Ok, I'm done") evt.set() + def waiter(): '''After 3 seconds the get call will unblock''' print("I'll wait for you") @@ -798,26 +799,26 @@

Queues

Worker john got task 2 Worker nancy got task 3 Worker steve got task 4 -Worker nancy got task 5 -Worker john got task 6 +Worker john got task 5 +Worker nancy got task 6 Worker steve got task 7 Worker john got task 8 Worker nancy got task 9 Worker steve got task 10 -Worker nancy got task 11 -Worker john got task 12 +Worker john got task 11 +Worker nancy got task 12 Worker steve got task 13 Worker john got task 14 Worker nancy got task 15 Worker steve got task 16 -Worker nancy got task 17 -Worker john got task 18 +Worker john got task 17 +Worker nancy got task 18 Worker steve got task 19 Worker john got task 20 Worker nancy got task 21 Worker steve got task 22 -Worker nancy got task 23 -Worker john got task 24 +Worker john got task 23 +Worker nancy got task 24 Quitting time! Quitting time! Quitting time! @@ -880,21 +881,21 @@

Queues

Worker john got task 2 Worker bob got task 3 Worker steve got task 4 -Worker bob got task 5 -Worker john got task 6 +Worker john got task 5 +Worker bob got task 6 Assigned all work in iteration 1 Worker steve got task 7 Worker john got task 8 Worker bob got task 9 Worker steve got task 10 -Worker bob got task 11 -Worker john got task 12 +Worker john got task 11 +Worker bob got task 12 Worker steve got task 13 Worker john got task 14 Worker bob got task 15 Worker steve got task 16 -Worker bob got task 17 -Worker john got task 18 +Worker john got task 17 +Worker bob got task 18 Assigned all work in iteration 2 Worker steve got task 19 Quitting time! @@ -955,6 +956,7 @@

Groups and Pools

group.map(hello_from, xrange(3)) + def intensive(n): gevent.sleep(3 - n) return 'task', n @@ -976,11 +978,11 @@

Groups and Pools


 Size of group 3
-Hello from Greenlet 36360912
+Hello from Greenlet 4340152592
 Size of group 3
-Hello from Greenlet 36361392
+Hello from Greenlet 4340928912
 Size of group 3
-Hello from Greenlet 36362352
+Hello from Greenlet 4340928592
 Ordered
 ('task', 0)
 ('task', 1)
@@ -1165,6 +1167,7 @@ 

Thread Locals

WSGIServer(('', 8000), application).serve_forever() +
@@ -1341,14 +1344,13 @@

Gevent ZeroMQ

which being a Request-Response socket pair. A socket has two methods of interest send and recv, both of which are normally blocking operations. But this is remedied by a briliant -library by Travis Cline which -uses gevent.socket to poll ZeroMQ sockets in a non-blocking -manner. You can install gevent-zeromq from PyPi via: pip install -gevent-zeromq

+library (is now part of pyzmq) +by Travis Cline which uses gevent.socket +to poll ZeroMQ sockets in a non-blocking manner.


-# Note: Remember to ``pip install pyzmq gevent_zeromq``
+# Note: Remember to ``pip install pyzmq``
 import gevent
-from gevent_zeromq import zmq
+import zmq.green as zmq
 
 # Global Context
 context = zmq.Context()
@@ -1536,6 +1538,7 @@ 

Long Polling

except Empty: pass + gevent.spawn(producer) WSGIServer(('', 8000), ajax_endpoint).serve_forever() @@ -1707,4 +1710,4 @@

Chat Server

- + \ No newline at end of file diff --git a/tutorial.md b/tutorial.md index 77c5475..328043e 100644 --- a/tutorial.md +++ b/tutorial.md @@ -1179,15 +1179,14 @@ ZeroMQ provides a variety of socket primitives, the simplest of which being a Request-Response socket pair. A socket has two methods of interest ``send`` and ``recv``, both of which are normally blocking operations. But this is remedied by a briliant -library by [Travis Cline](https://github.com/traviscline) which -uses gevent.socket to poll ZeroMQ sockets in a non-blocking -manner. You can install gevent-zeromq from PyPi via: ``pip install -gevent-zeromq`` +[library](https://github.com/tmc/gevent-zeromq) (is now part of PyZMQ) +by [Travis Cline](https://github.com/tmc) which uses gevent.socket +to poll ZeroMQ sockets in a non-blocking manner. [[[cog -# Note: Remember to ``pip install pyzmq gevent_zeromq`` +# Note: Remember to ``pip install pyzmq`` import gevent -from gevent_zeromq import zmq +import zmq.green as zmq # Global Context context = zmq.Context() From e126190f1b45419bcd3e2780f6c0b3cbc235166b Mon Sep 17 00:00:00 2001 From: Tim Chan Date: Sun, 6 Dec 2015 15:01:28 -0800 Subject: [PATCH 29/38] Fixed misspellings in tutorial.md. --- tutorial.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorial.md b/tutorial.md index f39e33e..37112a2 100644 --- a/tutorial.md +++ b/tutorial.md @@ -493,7 +493,7 @@ with Timeout(time_to_wait, TooLong):
In addition, gevent also provides timeout arguments for a -variety of Greenlet and data stucture related calls. For example: +variety of Greenlet and data structure related calls. For example: [[[cog import gevent @@ -569,7 +569,7 @@ function select at 0x1924de8 Python's runtime allows for most objects to be modified at runtime including modules, classes, and even functions. This is generally an -astoudingly bad idea since it creates an "implicit side-effect" that is +astoundingly bad idea since it creates an "implicit side-effect" that is most often extremely difficult to debug if problems occur, nevertheless in extreme situations where a library needs to alter the fundamental behavior of Python itself monkey patches can be used. In this case gevent @@ -1178,7 +1178,7 @@ distributed applications. ZeroMQ provides a variety of socket primitives, the simplest of which being a Request-Response socket pair. A socket has two methods of interest ``send`` and ``recv``, both of which are -normally blocking operations. But this is remedied by a briliant +normally blocking operations. But this is remedied by a brilliant [library](https://github.com/tmc/gevent-zeromq) (is now part of PyZMQ) by [Travis Cline](https://github.com/tmc) which uses gevent.socket to poll ZeroMQ sockets in a non-blocking manner. From 6461136797fd74a4bc53afd8f12f34efed953a4c Mon Sep 17 00:00:00 2001 From: jianbin-netskope Date: Fri, 15 Apr 2016 14:58:27 -0700 Subject: [PATCH 30/38] Update tutorial.md Make number of sync tasks to 10 instead of 9, and consistent with async tasks. --- tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial.md b/tutorial.md index 37112a2..e67d566 100644 --- a/tutorial.md +++ b/tutorial.md @@ -167,7 +167,7 @@ def task(pid): print('Task %s done' % pid) def synchronous(): - for i in range(1,10): + for i in xrange(10): task(i) def asynchronous(): From 372aaacbd245b9ff479cf8128838a110aedd710c Mon Sep 17 00:00:00 2001 From: Jianbin Wei Date: Sat, 16 Apr 2016 09:13:21 -0700 Subject: [PATCH 31/38] update example to also show Queue maxsize effect; update index.html --- index.html | 55 ++++++++++++++++++++++++++++++++++++----------------- tutorial.md | 2 ++ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index 4437853..f807153 100644 --- a/index.html +++ b/index.html @@ -244,7 +244,7 @@

Synchronous & Asynchronous Execu print('Task %s done' % pid) def synchronous(): - for i in range(1,10): + for i in xrange(10): task(i) def asynchronous(): @@ -261,6 +261,7 @@

Synchronous & Asynchronous Execu


 Synchronous:
+Task 0 done
 Task 1 done
 Task 2 done
 Task 3 done
@@ -271,16 +272,16 @@ 

Synchronous & Asynchronous Execu Task 8 done Task 9 done Asynchronous: -Task 7 done +Task 1 done +Task 6 done +Task 0 done +Task 3 done Task 4 done Task 5 done -Task 8 done +Task 7 done Task 9 done -Task 0 done -Task 1 done Task 2 done -Task 3 done -Task 6 done +Task 8 done

In the synchronous case all the tasks are run sequentially, which results in the main programming blocking ( @@ -590,7 +591,7 @@

Timeouts

In addition, gevent also provides timeout arguments for a -variety of Greenlet and data stucture related calls. For example:

+variety of Greenlet and data structure related calls. For example:


 import gevent
 from gevent import Timeout
@@ -668,7 +669,7 @@ 

Monkeypatching

Python's runtime allows for most objects to be modified at runtime including modules, classes, and even functions. This is generally an -astoudingly bad idea since it creates an "implicit side-effect" that is +astoundingly bad idea since it creates an "implicit side-effect" that is most often extremely difficult to debug if problems occur, nevertheless in extreme situations where a library needs to alter the fundamental behavior of Python itself monkey patches can be used. In this case gevent @@ -858,10 +859,12 @@

Queues

""" for i in xrange(1,10): + print('Assigned work %s in iteration 1' % (i)) tasks.put(i) print('Assigned all work in iteration 1') for i in xrange(10,20): + print('Assigned work %s in iteration 2' % (i)) tasks.put(i) print('Assigned all work in iteration 2') @@ -875,22 +878,41 @@

Queues


+Assigned work 1 in iteration 1
+Assigned work 2 in iteration 1
+Assigned work 3 in iteration 1
+Assigned work 4 in iteration 1
 Worker steve got task 1
 Worker john got task 2
 Worker bob got task 3
+Assigned work 5 in iteration 1
+Assigned work 6 in iteration 1
+Assigned work 7 in iteration 1
 Worker steve got task 4
 Worker john got task 5
 Worker bob got task 6
+Assigned work 8 in iteration 1
+Assigned work 9 in iteration 1
 Assigned all work in iteration 1
+Assigned work 10 in iteration 2
 Worker steve got task 7
 Worker john got task 8
 Worker bob got task 9
+Assigned work 11 in iteration 2
+Assigned work 12 in iteration 2
+Assigned work 13 in iteration 2
 Worker steve got task 10
 Worker john got task 11
 Worker bob got task 12
+Assigned work 14 in iteration 2
+Assigned work 15 in iteration 2
+Assigned work 16 in iteration 2
 Worker steve got task 13
 Worker john got task 14
 Worker bob got task 15
+Assigned work 17 in iteration 2
+Assigned work 18 in iteration 2
+Assigned work 19 in iteration 2
 Worker steve got task 16
 Worker john got task 17
 Worker bob got task 18
@@ -975,11 +997,11 @@ 

Groups and Pools


 Size of group 3
-Hello from Greenlet 139643393732848
+Hello from Greenlet 4405439216
 Size of group 3
-Hello from Greenlet 139643393733968
+Hello from Greenlet 4405439056
 Size of group 3
-Hello from Greenlet 139643393733488
+Hello from Greenlet 4405440336
 Ordered
 ('task', 0)
 ('task', 1)
@@ -1339,11 +1361,10 @@ 

Gevent ZeroMQ

ZeroMQ provides a variety of socket primitives, the simplest of which being a Request-Response socket pair. A socket has two methods of interest send and recv, both of which are -normally blocking operations. But this is remedied by a briliant -library by Travis Cline which -uses gevent.socket to poll ZeroMQ sockets in a non-blocking -manner. You can install gevent-zeromq from PyPi via: pip install -gevent-zeromq

+normally blocking operations. But this is remedied by a brilliant +library (is now part of PyZMQ) +by Travis Cline which uses gevent.socket +to poll ZeroMQ sockets in a non-blocking manner.


 # Note: Remember to ``pip install pyzmq``
 import gevent
diff --git a/tutorial.md b/tutorial.md
index e67d566..ca71973 100644
--- a/tutorial.md
+++ b/tutorial.md
@@ -745,10 +745,12 @@ def boss():
     """
 
     for i in xrange(1,10):
+        print('Assigned work %s in iteration 1' % (i))
         tasks.put(i)
     print('Assigned all work in iteration 1')
 
     for i in xrange(10,20):
+        print('Assigned work %s in iteration 2' % (i))
         tasks.put(i)
     print('Assigned all work in iteration 2')
 

From 483b00616307eb9c85619de1ae60a8390aff8444 Mon Sep 17 00:00:00 2001
From: yuankai 
Date: Tue, 4 Oct 2016 14:42:09 -0400
Subject: [PATCH 32/38] fixed a typo of "an individual worker"

---
 index.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/index.html b/index.html
index 4437853..0737cf7 100644
--- a/index.html
+++ b/index.html
@@ -853,7 +853,7 @@ 

Queues

def boss(): """ - Boss will wait to hand out work until a individual worker is + Boss will wait to hand out work until an individual worker is free since the maxsize of the task queue is 3. """ @@ -1706,4 +1706,4 @@

Chat Server

- \ No newline at end of file + From adb2cfc697748390b3e9059c0d0ad6c045eff316 Mon Sep 17 00:00:00 2001 From: godsdog Date: Tue, 17 Jan 2017 22:57:25 +0200 Subject: [PATCH 33/38] Rename gevent.coros to gevent.lock Module ``gevent.coros`` was replaced by ``gevent.lock`` and was removed in version 1.2. --- index.html | 2 +- tutorial.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 0737cf7..c13e016 100644 --- a/index.html +++ b/index.html @@ -1050,7 +1050,7 @@

Locks and Semaphores


 from gevent import sleep
 from gevent.pool import Pool
-from gevent.coros import BoundedSemaphore
+from gevent.lock import BoundedSemaphore
 
 sem = BoundedSemaphore(2)
 
diff --git a/tutorial.md b/tutorial.md
index 37112a2..13e6970 100644
--- a/tutorial.md
+++ b/tutorial.md
@@ -888,7 +888,7 @@ releases its acquisition.
 [[[cog
 from gevent import sleep
 from gevent.pool import Pool
-from gevent.coros import BoundedSemaphore
+from gevent.lock import BoundedSemaphore
 
 sem = BoundedSemaphore(2)
 

From b04a5540b0ae629957f0ad3832d9f8b8e563a8f2 Mon Sep 17 00:00:00 2001
From: Chunlin Zhang 
Date: Mon, 17 Apr 2017 14:31:33 +0800
Subject: [PATCH 34/38] fix gevent-websocket source code url

---
 index.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/index.html b/index.html
index 19545f4..fee66b5 100644
--- a/index.html
+++ b/index.html
@@ -147,7 +147,7 @@ 

Synchronous & Asynchronous Execu into a collection of subtasks which are scheduled to run simultaneously or asynchronously, instead of one at a time or synchronously. A switch between the two subtasks is known as a context switch.

-

A context switch in gevent is done through yielding. In this +

A context switch in gevent is done through yielding. In this example we have two contexts which yield to each other through invoking gevent.sleep(0).


@@ -1564,7 +1564,7 @@ 

Long Polling

Websockets

-

Websocket example which requires gevent-websocket.

+

Websocket example which requires gevent-websocket.

 # Simple gevent-websocket server
 import json

From 32a39dc0774593b60f2dcb2b5e9328e30aeac7ac Mon Sep 17 00:00:00 2001
From: randvis 
Date: Wed, 30 Aug 2017 14:13:19 +0800
Subject: [PATCH 35/38] Synchronize tutorial.md with previous fix #58.

---
 tutorial.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tutorial.md b/tutorial.md
index f2d4240..679809f 100644
--- a/tutorial.md
+++ b/tutorial.md
@@ -740,7 +740,7 @@ def worker(name):
 
 def boss():
     """
-    Boss will wait to hand out work until a individual worker is
+    Boss will wait to hand out work until an individual worker is
     free since the maxsize of the task queue is 3.
     """
 

From 11b8efeb85385d3cc3a232dfefdd6d73c6ac8ec3 Mon Sep 17 00:00:00 2001
From: randvis 
Date: Wed, 30 Aug 2017 14:39:26 +0800
Subject: [PATCH 36/38] Synchronize tutorial.md with previous fix #60.

---
 tutorial.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tutorial.md b/tutorial.md
index 679809f..010d37f 100644
--- a/tutorial.md
+++ b/tutorial.md
@@ -1379,7 +1379,7 @@ WSGIServer(('', 8000), ajax_endpoint).serve_forever()
 
 ## Websockets
 
-Websocket example which requires gevent-websocket.
+Websocket example which requires gevent-websocket.
 
 
 

From ee7297aa7e9acb438b4086390d78902617f9b11b Mon Sep 17 00:00:00 2001
From: randvis 
Date: Wed, 30 Aug 2017 15:03:27 +0800
Subject: [PATCH 37/38] Fix #9.

---
 index.html  | 6 +++---
 tutorial.md | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/index.html b/index.html
index fee66b5..ff3c4f7 100644
--- a/index.html
+++ b/index.html
@@ -536,7 +536,7 @@ 

Program Shutdown

This results in so called "zombie processes" which need to be killed from outside of the Python interpreter.

A common pattern is to listen SIGQUIT events on the main program -and to invoke gevent.shutdown before exit.

+and to invoke gevent.kill or gevent.killall before exit.

 import gevent
 import signal
@@ -545,8 +545,8 @@ 

Program Shutdown

gevent.sleep(1000) if __name__ == '__main__': - gevent.signal(signal.SIGQUIT, gevent.kill) thread = gevent.spawn(run_forever) + gevent.signal(signal.SIGQUIT, gevent.kill, thread) thread.join()
@@ -1727,4 +1727,4 @@

Chat Server

- + \ No newline at end of file diff --git a/tutorial.md b/tutorial.md index 010d37f..bcf78f9 100644 --- a/tutorial.md +++ b/tutorial.md @@ -77,7 +77,7 @@ into a collection of subtasks which are scheduled to run simultaneously or *asynchronously*, instead of one at a time or *synchronously*. A switch between the two subtasks is known as a *context switch*. -A context switch in gevent is done through *yielding*. In this +A context switch in gevent is done through *yielding*. In this example we have two contexts which yield to each other through invoking ``gevent.sleep(0)``. @@ -434,7 +434,7 @@ This results in so called "zombie processes" which need to be killed from outside of the Python interpreter. A common pattern is to listen SIGQUIT events on the main program -and to invoke ``gevent.shutdown`` before exit. +and to invoke ``gevent.kill`` or ``gevent.killall`` before exit.
 import gevent
@@ -444,8 +444,8 @@ def run_forever():
     gevent.sleep(1000)
 
 if __name__ == '__main__':
-    gevent.signal(signal.SIGQUIT, gevent.kill)
     thread = gevent.spawn(run_forever)
+    gevent.signal(signal.SIGQUIT, gevent.kill, thread)
     thread.join()
 
 
From 5d8b307bffd4dafd3e89c138419c95c2f488f627 Mon Sep 17 00:00:00 2001 From: abhijaygh <42239188+abhijaygh@users.noreply.github.com> Date: Tue, 16 Oct 2018 00:35:01 +0530 Subject: [PATCH 38/38] update css i hope making changes in text decoration,padding and font doesnot affect your code --- gevent.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gevent.css b/gevent.css index 6ae1014..c8eae55 100644 --- a/gevent.css +++ b/gevent.css @@ -17,6 +17,7 @@ a { color: inherit; + text-decoration:none; } pre { @@ -40,7 +41,7 @@ p code, li code { display: block; margin-bottom: 0px; padding: 0px; - font-family: sans; + font-family: monospace; font-weight: bold; width: 200px; padding: 0.5em; @@ -52,7 +53,7 @@ p code, li code { h1 { text-align: center; - padding-bottom: 5px; + padding-bottom: 6px; margin-top: 50px; margin-bottom: 50px; }