From 976f18e922219200f090966c43b26438b9f5a019 Mon Sep 17 00:00:00 2001
From: Alexander James Phillips Introduction
your existing concurrency problems and start writing asynchronous
applications today.
In chronological order of contribution: +
In chronological order of contribution: Stephen Diehl Jérémy Bethmont sww @@ -268,7 +268,7 @@
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 @@
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.
-# 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?=
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.@@ -188,7 +188,7 @@Only one greenlet is ever running at any given time.
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 @@ In the synchronous case all the tasks are run sequentially, which results in the main programming blocking ( @@ -397,7 +397,7 @@
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
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 @@
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 @@
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 @@ @@ -1289,13 +1289,13 @@@@ -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.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()
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?=@@ -1338,7 +1338,7 @@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))
-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
@@ -1653,7 +1653,7 @@-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.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 XiaDate: 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()
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