Skip to content

Commit e4fbcf0

Browse files
committed
Added section on monkey patching.
1 parent 67d97a1 commit e4fbcf0

2 files changed

Lines changed: 119 additions & 9 deletions

File tree

index.html

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ <h3 class="author">
5757
<li><a href="#greenlet-state">Greenlet State</a></li>
5858
<li><a href="#program-shutdown">Program Shutdown</a></li>
5959
<li><a href="#timeouts">Timeouts</a></li>
60+
<li><a href="#monkeypatching">Monkeypatching</a></li>
6061
</ul>
6162
</li>
6263
<li><a href="#data-structures">Data Structures</a><ul>
@@ -250,16 +251,16 @@ <h2 id="synchronous-asynchronous-execution">Synchronous &amp; Asynchronous Execu
250251
Task 8 done
251252
Task 9 done
252253
Asynchronous:
254+
Task 0 done
255+
Task 9 done
253256
Task 1 done
254-
Task 2 done
257+
Task 4 done
258+
Task 6 done
255259
Task 5 done
256-
Task 7 done
257-
Task 9 done
258260
Task 8 done
259-
Task 0 done
260261
Task 3 done
261-
Task 4 done
262-
Task 6 done
262+
Task 2 done
263+
Task 7 done
263264
</pre></code></p>
264265
<p>In the synchronous case all the tasks are run sequentially,
265266
which results in the main programming <em>blocking</em> (
@@ -612,6 +613,58 @@ <h2 id="timeouts">Timeouts</h2>
612613
Thread 2 timed out
613614
Thread 3 timed out
614615
</pre></code></p>
616+
<h2 id="monkeypatching">Monkeypatching</h2>
617+
<p>Alas we come to dark corners of Gevent. I've avoided mentioning
618+
monkey patching up until now to try and motivate the powerful
619+
coroutine patterns but the time has come to discuss the dark arts
620+
of monkey-patching. If you noticed above we invoked the commnad
621+
<code>monkey.patch_socket()</code>. This is a purely side-effectful command to
622+
modify the standard library's socket library</p>
623+
<pre>
624+
<code class="python">import socket
625+
print( socket.socket )
626+
627+
print "After monkey patch"
628+
from gevent import monkey
629+
monkey.patch_socket()
630+
print( socket.socket )
631+
632+
import select
633+
print select.select
634+
monkey.patch_select()
635+
print "After monkey patch"
636+
print( select.select )
637+
</code>
638+
</pre>
639+
640+
<pre>
641+
<code class="python">class 'socket.socket'
642+
After monkey patch
643+
class 'gevent.socket.socket'
644+
645+
After monkey patch
646+
built-in function select
647+
function select at 0x1924de8
648+
</code>
649+
</pre>
650+
651+
<p>Python's runtime allows for most objects to be modified at runtime
652+
including modules, classes, and even functions. This is generally an
653+
astoudingly bad idea since it creates an "implicit side-effect" that is
654+
most often extremely difficult to debug if problems occur, nevertheless
655+
in extreme situations where a library needs to alter the fundamental
656+
behavior of Python itself monkey patches can be used. In this case gevent
657+
is capable of patching most of the blocking system calls in the standard
658+
library including those in <code>socket</code>, <code>ssl</code>, <code>threading</code> and
659+
<code>select</code> modules to instead behave cooperatively.</p>
660+
<p>For example, the Redis python bindings normally uses regular tcp
661+
sockets to communicate with the <code>redis-server</code> instance. Simply
662+
by invoking <code>gevent.monkey.patch_all()</code> we can make the redis
663+
bindings schedule requests cooperatively and work with the rest
664+
of our gevent stack.</p>
665+
<p>This lets us integrate libraries that would not normally work with
666+
gevent without ever writing a single line of code. While monkey-patching
667+
is still evil, in this case it is a "usefull evil".</p>
615668
<h1 id="data-structures">Data Structures</h1>
616669
<h2 id="events">Events</h2>
617670
<p>Events are a form of asynchronous communication between
@@ -896,11 +949,11 @@ <h2 id="groups-and-pools">Groups and Pools</h2>
896949
<p></code>
897950
<pre><code class="python">
898951
Size of group 3
899-
Hello from Greenlet 41900624
952+
Hello from Greenlet 42121488
900953
Size of group 3
901-
Hello from Greenlet 41900944
954+
Hello from Greenlet 42119248
902955
Size of group 3
903-
Hello from Greenlet 41899024
956+
Hello from Greenlet 42120208
904957
Ordered
905958
('task', 0)
906959
('task', 1)

tutorial.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,63 @@ except Timeout:
511511
]]]
512512
[[[end]]]
513513

514+
## Monkeypatching
515+
516+
Alas we come to dark corners of Gevent. I've avoided mentioning
517+
monkey patching up until now to try and motivate the powerful
518+
coroutine patterns but the time has come to discuss the dark arts
519+
of monkey-patching. If you noticed above we invoked the commnad
520+
``monkey.patch_socket()``. This is a purely side-effectful command to
521+
modify the standard library's socket library
522+
523+
<pre>
524+
<code class="python">import socket
525+
print( socket.socket )
526+
527+
print "After monkey patch"
528+
from gevent import monkey
529+
monkey.patch_socket()
530+
print( socket.socket )
531+
532+
import select
533+
print select.select
534+
monkey.patch_select()
535+
print "After monkey patch"
536+
print( select.select )
537+
</code>
538+
</pre>
539+
540+
<pre>
541+
<code class="python">class 'socket.socket'
542+
After monkey patch
543+
class 'gevent.socket.socket'
544+
545+
built-in function select
546+
After monkey patch
547+
function select at 0x1924de8
548+
</code>
549+
</pre>
550+
551+
Python's runtime allows for most objects to be modified at runtime
552+
including modules, classes, and even functions. This is generally an
553+
astoudingly bad idea since it creates an "implicit side-effect" that is
554+
most often extremely difficult to debug if problems occur, nevertheless
555+
in extreme situations where a library needs to alter the fundamental
556+
behavior of Python itself monkey patches can be used. In this case gevent
557+
is capable of patching most of the blocking system calls in the standard
558+
library including those in ``socket``, ``ssl``, ``threading`` and
559+
``select`` modules to instead behave cooperatively.
560+
561+
For example, the Redis python bindings normally uses regular tcp
562+
sockets to communicate with the ``redis-server`` instance. Simply
563+
by invoking ``gevent.monkey.patch_all()`` we can make the redis
564+
bindings schedule requests cooperatively and work with the rest
565+
of our gevent stack.
566+
567+
This lets us integrate libraries that would not normally work with
568+
gevent without ever writing a single line of code. While monkey-patching
569+
is still evil, in this case it is a "usefull evil".
570+
514571
# Data Structures
515572

516573
## Events

0 commit comments

Comments
 (0)