Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 94 lines (71 sloc) 3.73 kb
284d62f updated README.twisted
Denis Bilenko authored
1 --work in progress--
2
3 Introduction
4 ------------
5 Twisted provides solid foundation for asynchronous programming in Python.
6 Eventlet makes asynchronous programming look like synchronous, thus
7 achieving higher signal-to-noise ratio than traditional twisted programs have.
8
9 Eventlet working on top of twisted, provides:
10 * [stable twisted]
11 * [usable and readable synchronous style]
12 * existing twisted code can be used without any changes
13 * existing blocking code can be used after trivial changes applied
14
15
16 Coroutines
17 ----------
b136163 started a doc on how it works
Denis Bilenko authored
18
19 To understand how eventlet works, one has to understand how to use greenlet:
20 http://codespeak.net/py/dist/greenlet.html
21
284d62f updated README.twisted
Denis Bilenko authored
22 Essential points
23
b136163 started a doc on how it works
Denis Bilenko authored
24 * Every greenlet except MAIN has a parent. When an exception happen in the greenlet
25 it is propogated to the parent greenlet (special case is GreenletExit, in that case
26 the greenlet silently dies)
27 * Parent can be reassigned (cycle would be detected and rejected with ValueError)
28 ...
29
284d62f updated README.twisted
Denis Bilenko authored
30 greenlet == coroutine == green thread == microthread in this document
31
32
33 How does eventlet work
34 ----------------------
35
36 Twisted's reactor and eventlet's hub are very similar in what they do.
37 Both continuously call select (or poll or similar) on the list of registered
38 descriptors (this is called polling) and each time a specific event is
39 fired, the associated callback function is called. In addition, both
40 maintain a list of scheduled calls.
b136163 started a doc on how it works
Denis Bilenko authored
41
284d62f updated README.twisted
Denis Bilenko authored
42 Polling is performed by the main loop - a function that both reactor and hub have.
43 However, while with twisted you explicitly start it by calling reactor.run(), with
44 eventlet the main loop is running in a dedicated greenlet and is started implicitly
45 upon the first switch into that greenlet. When an event is fired, the callback
46 perform switch to the waiting greenlet.
b136163 started a doc on how it works
Denis Bilenko authored
47
284d62f updated README.twisted
Denis Bilenko authored
48 So, to perform a `blocking' operation that blocks this greenlet but not the others,
49 you switch() into the main loop's greenlet with some additional preparations,
50 as shown in the following figure.
51
52 = blocking operation RECV on socket d =
b136163 started a doc on how it works
Denis Bilenko authored
53
54 user's greenlet (USER) main loop's greenlet (MAIN_LOOP)
55 |
56 (inside d.recv() call)
57 |
58 add_descriptor(d, RECV)
59 |
60 data=MAIN_LOOP.switch() ---------> poll for events
284d62f updated README.twisted
Denis Bilenko authored
61 ^---------------------\ |
62 | ... ---------------------------> may execute other greenlets here
63 | |
64 | event RECV on descriptor d?
65 | |
66 | d.remove_descriptor(d, RECV)
67 | |
68 | data = d.recv() # calling blocking op that will return immediately
69 | |
70 \--------- USER.switch(data) # argument data here becomes return value in user's switch
71 return data
72
73
74 TBW:
75
76 * green package
77 modules that mimic modules in standard library, but actually do the non-blocking stuff as described above.
78
79 * how to convert protocol implemented in twisted to `blocking' mode.
80 see eventlet.twisteds.util.block_on
81
82 One can also look at Corotwine for an ideas.
83 Corotwine is another attempt to use twisted together with greentlets.
84 protocol <-> buffer <-> greenlet
85
86 * how to convert real blocking code.
87 For simple cases: block_on(reactor.callInThread(func, args))
b136163 started a doc on how it works
Denis Bilenko authored
88
284d62f updated README.twisted
Denis Bilenko authored
89 When single deferred is not enough: Queue subclass that has list of
90 associated channels with it and a descriptor (obtained with os.pipe()).
91 Every time, queue.put is called, eQueue does descriptor.write(byte).
92 The descriptor is registered with the hub, so the callback is called
93 which gets the value from the Queue and puts it in all associated channels.
Something went wrong with that request. Please try again.