Dave Peticolas
Nina Evseenko
1.1
. . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3
1.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
10
12
13
2.1
. . . . . . . . . . . . . . . . . . .
13
2.2
. . . . . . . . . . . . . . . . .
13
2.3
. . . . . . . . . . . . . . . . . . . . . . . .
13
2.4
. . . . . . . . . . . . . . . . . . . . . .
15
2.5
. . . . . . . . . . . . . . . . . . . . . .
16
2.6
. . . . . . . . . . . . . . . . . . . . . . .
17
2.7
20
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Twisted
21
3.1
- Twisted . . . . . . . . . . . . . . . .
21
3.2
, Twisted
23
3.3
callback'?
3.4
, Twisted
3.5
, Twisted
3.6
, . . . . . . . . . . . . . . . . . . . . . . .
28
3.7
28
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
24
. . . . . . . . . . . . . . . . . . . . . .
26
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Twisted
27
29
4.1
Twisted
. . . . . . . . . . . . . . . . . .
29
4.2
Twisted . . . . . . . . . . . . . . . . . . . . . . .
30
4.3
callback' . . . . . . . . . . . . . . . . . . . . . . . .
32
4.4
34
4.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Twisted
35
36
5.1
. . . . . . . . . . . . . . . . .
5.2
. . . . . . . . . . . . . . . . . . . . . . . .
37
5.3
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
5.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
5.5
. . . . . . . . . . . . . . . . . . . . .
39
5.6
2.0: .0 . . . . . . . . . . . . .
40
5.7
45
. . . . . . . . . . . . . . . . . . . . . . .
36
5.8
5.9
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
45
45
46
6.1
. . . . . . . . . . . . . . . . . . . . . . . . .
46
6.2
3.0
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
6.3
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
6.4
. . . . . . . . . . . . . . . . . . . . . . . .
50
6.5
3.1
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
6.6
6.7
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
53
54
55
7.1
. . . . . . . . . . . .
7.2
Deferred . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
7.3
64
7.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
55
64
65
8.1
4.0
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
8.2
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
8.3
deferred', callback', . . . . . .
68
8.4
70
8.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Deferred',
71
72
9.1
callback'
. . . . . . . . . . . . . .
72
9.2
Deferred' . . . . . . . . . . . . . . .
77
9.3
Callback' Errback', . . . . . . . . . . . . . . . . .
81
9.4
Deferred
. . . . . . . . . . . . . . . . . . . . . . .
81
9.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
9.6
. . . . . . . . . . . . . . . . . . . . . . . . . . .
10
82
84
10.1 5.0
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.2 5.1
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
10.3
10.4
. . . . . . . . . . . . . . . . . . . . . . . . . . .
84
92
11
93
11.1 Twisted . . . . . . . . . . . . . . . . . . .
93
11.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
11.3
97
. . . . . . . . . . . . . . . . . . . . . . . . . . .
12 ,
98
12.1 . . . . . . . . . . . . . . . . . . . . . . . . .
98
12.2 . . . . . . . . . . . . . . . . . . .
98
12.3
99
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12.4
. . . . . . . . . . . . . . . . . . . . . . . . . 101
12.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
12.6
12.7
. . . . . . . . . . . . . . . . . . . . . . . . 102
. . . . . . . . . . . . . . . . . . . . . . . . . . . 103
13 Deferred' Deferred'
13.1
104
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
13.2 6.0
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
13.3 . . . . . . . . . . . . . . . . . . . . . . 109
13.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
13.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . 109
14 , Deferred Deferred'
14.1
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
14.2 1.0
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
14.3
14.4 2.0
14.5
. . . . . . . . . . . . . . . . . . . . . . . . . . 115
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
14.6
. . . . . . . . . . . . . . . . . . . . . . . . . . . 118
15
15.1
15.2
111
120
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
15.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
15.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
15.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . 123
16 Twisted
16.1
16.2
124
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
16.2.1 IService
. . . . . . . . . . . . . . . . . . . . . . . . . . 124
16.2.3 Application
. . . . . . . . . . . . . . . . . . . . . . . . 126
. . . . . . . . . . . . . . . . . . . . . 132
. . . . . . . . . . . . . . . . . . . . . . . . . . 135
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
16.7
. . . . . . . . . . . . . . . . . . . . . . . . . . . 138
17 callback'
17.1
139
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
17.1.1 . . . . . . . . . . . . . . . 139
17.2 callback' . . . . . . . . . . . . . . . . . . . . . . 141
17.2.1 inlineCallbacks
17.3 7.0
. . . . . . . . . . . . . . . . . . . . . . 143
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
17.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
17.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
17.6
. . . . . . . . . . . . . . . . . . . . . . . . . . . 148
18 Deferred'
18.1
150
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
18.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
18.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . 155
19 deferred'
19.1
157
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
19.2 deferred'
. . . . . . . . . . . . . . . . . . 158
19.3 Deferred'
. . . . . . . . . . . . 161
. . . . . . . . . . . . . . . . . . . . . . . . . . . 169
20 : Twisted Erlang
20.1
171
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
20.2 . . . . . . . . . . . . . . 172
20.3 Erlang
. . . . . . . . . . . . . . . . . . . . . . . . 173
. . . . . . . . . . . 183
21 Twisted Haskell
21.1
184
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
21.2
21.3 Haskell
. . . . . . . . . . . . . . . 184
. . . . . . . . . . . . . . . . . . . . . . . . . . 187
21.4 . . . . . . . . . . . . . . . 189
21.5
22
. . . . . . 190
191
22.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
22.2
22.3
. . . . . . . . . . . . . . . . . . . . . . . 191
. . . . . . . . . . . . . . . . . . . . . . . . . . . 191
22.4
. . . . . . . . . . . . . . . . . . . . . . 191
. ,
Twisted Introduction, Dave Peticolas.
1.1
Twisted : -
, Twisted? ,
.
, . Twisted , . Twisted ,
, . , Twisted
, Twisted, , .
, , - Twisted.
Twisted. ,
Python'. Twisted,
,
. Twisted - ,
. , Twisted, , Twisted , .
.
, , Twisted. - .
1.2
, . , ,
, .
,
, , . , : ,
.
, , -
, 1 :
. 1:
. ,
, . , , , .
,
2:
. 2:
. ,
/ , , . ,
, ,
. ,
, . , .
, . , , ,
2.
3:
. 3: Ac
.
, , ,
, - .
, , ,
2, 3,
.
.
. -
. , ,
,
. , ,
. , .
, ,
. ,
,
.
1.3
, , ,
, , .
, .
, .
, ,
,
, .
, ,
, ,
.
?
. -
, ,
, .
, , . , ,
, , . , ,
4:
, () . ? -
10
. 4:
-,
.
,
. , , -,
. (blocking
program).
, 4 ,
3.
. - , , , , . , ,
(non-blocking
program). , , ,
. ,
, .
, :
1. ,
, .
11
2. -, ,
, , .
3. .
(, web ) -. -
. . ,
Twisted - .
1.4
. , - , , ( Twisted),
, , Python'.
12
.
- .
2.1
, Python' Python'. ,
Python- socket, . Python,
, , .
2.2
Linux'. ,
Unix (Mac OSX FreeBSD).
, Python Twisted. Python
2.5 Twisted 8.2.0.
. .
zip tar , git . git
, git , , ,
.
SVG. :
2.3
, ,
, , ,
13
. , ,
, loopback
. - ,
, .
- , . poetry
John Donne, W.B. Yeats, Edgar Allen Poe. ,
.
blocking-server/slowpoetry.py.
:
--num-bytes
--delay.
, 50 5
, :
14
, "loopback".
,
iface.
, ,
,
, .
, .
,
Peak Oil , , , ,
, . , , ,
, , -
,
.
c .
2.4
,
.
,
1. ,
:
15
,
. ,
,
,
. ,
:
Task 1: get
Task 1: got
Task 2: get
Task 2: got
Task 3: get
Task 3: got
Got 3 poems
1,
. .
--delay.
.
,
.
2.5
, Twisted. . , .
, . , async-client/get-poetry.py, :
from
from
from
from
from
127.0.0.1:10000
127.0.0.1:10001
127.0.0.1:10002
127.0.0.1:10000
127.0.0.1:10001
16
, . ,
, . , , 3.
--delay
(,
, ) ,
"" , . .
, , , 10 ,
23
. 3
4. ,
, .
, : , print!
. shell', , print
. , ,
pipeline ,
-
. Twisted , , , print, , Twisted.
2.6
. :
1.
.
2. , , setblocking(0).
3. select select () ,
17
.
4. ,
.
get_poetry.
:
1. () select',
.
2. , , , ,
.
3. .
( main),
. . , ,
.
. select' ,
, ,
, .
( ),
,
get_poetry. ,
, .
, , , reactor. 5:
18
. 5: reactor'
reactor', . ,
"event loop". , select ,
select -. select
, "" ,
. , select - -, (
) . API,
, ,
select, . , , :
( ) ,
-.
, select
- . (reactive system) -,
-, .
-,
.
,
reactor, ,
. .
reactor
, :
19
1.
-.
2. ,
.
reactor :
1. ,
.
2. ,
reactor .
3. ,
.
, Twisted - , -
reactor .
Twisted,
Twisted!
2.7
1. ,
.
2. get_poetry,
? ?
3. get_poetry ,
?
?
20
Twisted
3.1
- Twisted
, Twisted. C Twisted , c .
2, Twisted
8.2.0. API Twisted , API,
,
c . Twisted,
.
Twisted .
basic-twisted/simple.py.
python basic-twisted/simple.py
, Twisted - Reactor, Twisted ,
reactor event loop,
Twisted . reactor, ,
.
. , CtrlC, .
- - (, ). , ,
. , busy loop,
. , . ,
. reactor
5, , ( , select ).
:
1. Twisted reactor.run().
2. , .
, main .
21
3. .
4. , .
5. reactor , .
. Twisted reactor - Singleton. reactor, .
reactor twisted.internet,
. :
(twisted.internet.selectreactor.py).
Twisted .
2, select' -
. , Twisted select, Twisted . , twisted.internet.pollreactor, poll select.
twisted.internet.reactor. pollreactor:
22
3.2
, Twisted
Twisted, - . , , ,
:
def hello():
print 'Hello from the reactor loop!'
print 'Lately I feel like I\'m stuck in a rut.'
from twisted.internet import reactor
reactor.callWhenRunning(hello)
print 'Starting the reactor.'
reactor.run()
basic-twisted/hello.py. :
import traceback
def stack():
print 'The python stack:'
traceback.print_stack()
23
3.3
callback'?
Twisted , callback'.
Python Medusa asyncore . , GUI , GTK QT,
.
:
1. reactor .
2. , Twisted,
, .
3. .
4. ,
.
5. reactor
.
callback', .
24
6 , :
. 6: reactor,
6 callback':
1. callback' , Twisted
.
2. callback' , Twisted .
3. .
4. callback'.
callback-, Twisted . , callback'
. - callback'. , . Twisted
,
. , , Twisted .
25
( pipe)
. , , , Twisted API,
. , Python
. , os.system
, . Twisted, os.system Twisted API .
3.4
, Twisted
class Countdown(object):
counter = 5
def count(self):
from twisted.internet import reactor
if self.counter == 0:
reactor.stop()
else:
print self.counter, '...'
self.counter -= 1
reactor.callLater(1, self.count)
from twisted.internet import reactor
reactor.callWhenRunning(Countdown().count)
print 'Start!'
reactor.run()
print 'Stop!'
API callLater callback' Twisted. callLater callback - ,
- , callback.
.
26
Twisted callback ? ,
select' ? select timeout. timeout
, select' timeout.
timeout, .
timeout , event loop 5. Twisted timeout' ,
, callback'
. - callback
, callback
. callLater
, hard realtime.
:
Start!
5 ...
4 ...
3 ...
2 ...
1 ...
Stop!
, "Stop!" , , reactor
, reactor.run.
, .
3.5
, Twisted
Twisted callback',
, , callback . . basic-twisted/exception.py
callback' ,
:
def falldown():
raise Exception('I fall down.')
def upagain():
print 'But I get up again.'
reactor.stop()
from twisted.internet import reactor
reactor.callWhenRunning(falldown)
reactor.callWhenRunning(upagain)
print 'Starting the reactor.'
reactor.run()
27
, :
3.6
Twisted. Twisted .
3.7
1. countdown.py , , .
reactor, .
2. LoopingCall twisted.internet.task. countdown LoopingCall. start stop,
deferred'. deferred' .
28
Twisted
4.1
Twisted
Twisted . , , ,
. : . , Twisted. twisted-client-1/get-poetry.py.
:
from
from
from
from
from
from
127.0.0.1:10000
127.0.0.1:10001
127.0.0.1:10002
127.0.0.1:10000
127.0.0.1:10002
127.0.0.1:10001
, Twisted. , , . ,
. ,
, .
, , Twisted
API. Twisted ,
Twisted . , API, . , - ,
, Twisted.
Twisted PoetrySocket.
PoetrySocket , :
29
4.2
Twisted
Twisted , .
Interface. 8.0, Twisted
zope.interface ,
.
Interface Twisted, ,
.
- . Python
, Duck typing , ,
public , . , public (, , ...) , duck typing,
(!). , Interface -
, " ".
twisted.internet.interfaces addReader.
IReactorFDSet :
def addReader(reader):
"""
I add reader to the set of file descriptors to get read events for.
@param reader: An L{IReadDescriptor} provider that will be checked for
read events until it is removed from the reactor with
L{removeReader}.
30
@return: C{None}.
"""
IReactorFDSet - , Twisted
. , Twisted reactor addReader, . self,
public ,
self - (, self ).
.
:
1. , IReactorFDSet , ,
IReactorFDSet - .
2. .
zope.interface , ,
. ,
, .
.
3. Interface' , Python.
, , ,
, Glyph', Twisted,
.
, reader addReader
IReadDescriptor. ,
PoetrySocket .
:
class IReadDescriptor(IFileDescriptor):
def doRead():
"""
Some data is available for reading on your descriptor.
"""
1
http://glyph.twistedmatrix.com/2009/02/explaining-why-interfaces-are-great.html
31
class IFileDescriptor(ILoggingContext):
"""
A file descriptor.
"""
def fileno():
...
def connectionLost(reason):
...
, ,
leno , , connectionLost .
PoetrySocket .
IFileDescriptor ILoggingContext.
, ,
callback logPrex. interfaces.
, doRead , , . ? ,
Twisted, , .
, , .
4.3
callback'
Twisted . . , -
32
, Twisted, select ,
Twisted reactor.
doRead callback - callback. Twisted , , - ,
. 7:
. 7: doRead callback
, callback, , . 3, Twisted
- , .
, .
, Twisted , twisted-client-1/get-poetry-broken.py. :
1. , socket
.
2. callback doRead (
,
).
:
33
4.4
34
4.5
1. ,
.
2. callLater, , timeout,
, .
callLater, ,
, , .
35
Twisted
5.1
, Twisted. , .
, , , . Twisted ,
, . , - ,
, .
, , . -
Twisted "win32 ,
.
- . 1.0 Twisted ,
. . ,
Twisted API, .
, . ? "" , ?
, , , .
, -
.
, API Interface'.
, Twisted . , 1.0 4 IReadDescriptor:
" , ". Twisted Interface',
, , , . , , :
Twisted , .
, Twisted , ,
. , -
36
A F, F
. , B F,
, F ( B A,
, A).
- , Twisted . ,
, Twisted .
5.2
37
Twisted , , . 6
, :
5 6 - .
,
Twisted.
, , : Transport, Protocol Protocol Factory.
5.3
5.4
38
, FTP IMAP, , .
, , ,
.
, Twisted Protocol . , (, , ), Protocol.
Protocol ( ,
-).
Protocol ? IProtocol, makeConnection. - callback, Twisted
Transport
. Transport - , Protocol .
Twisted
.
twisted.protocols.basic. Twisted
, Protocol, ,
. , ,
,
.
5.5
Protocol,
Protocol , . Twisted , Twisted ,
Protocol " " .
Protocol - (Protocol Factory).
, Protocol Factory API IProtocolFactory, interfaces. Protocol Factory - Factory, .
buildProtocol Protocol . , Twisted ,
Protocol .
39
5.6
2.0: .0
2.0 Twisted .
twisted-client-2/get-poetry.py. , ,
. ,
.
, Twisted , .
print , ,
,
.
2.0 . socket,
socket . :
factory = PoetryClientFactory(len(addresses))
from twisted.internet import reactor
for address in addresses:
host, port = address
reactor.connectTCP(host, port, factory)
connectTCP. . - PoetryClientFactory.
- Protocol Factory ,
Twisted
PoetryProtocol .
, Factory, Protocol ,
PoetrySocket . , , Twisted
twisted.internet.protocol. Factory twisted.internet.protocol.Factory, ClientFactory,
(
, , ).
, Factory Twisted
buildProtocol.
:
Protocol ? ,
protocol PoetryClientFactory:
class PoetryClientFactory(ClientFactory):
task_num = 1
protocol = PoetryProtocol # tell base class what proto to build
Factory buildProtocol
, protocol (, PoetryProtocol),
factory , ""Factory. 8:
. 8: Protocol'
, factory Protocol
, Factory,
.
, Protocol , ,
6.
, factory Protocol' Protocol Factory, protocol Factory
Protocol. , Factory
Protocol.
41
. 9: Protocol Transport
, Protocol - (, , ). - dataReceived, :
42
. ,
, ,
poem.
, getHost Transport'
, . . ,
Transport ,
.
, ,
dataReceived. , 2.0,
twisted-client-2/get-poetry-stack.py.
, 2.0, , dataReceived
:
43
...
self.poetry_count -= 1
if self.poetry_count == 0:
...
, -
,
lock' ,
poem_nished . ,
44
reactor ( ). : reactor
callback , .
,
1.0. callback PoetryClientFactory :
5.7
, , .
. 2.1 twisted-client2/get-poetry-simple.py.
5.8
5.9
1. callLater , timeout ,
. loseConnection Transport ,
timeout',
timeout, .
2. stacktrace callback',
connectionLost.
45
6.1
.
(2.0) Transport, Protocol Protocol Factory.
. 2.0 ( 2.1) .
PoetryClientFactory
PoetryProtocols, , PoetryClientFactory.
, . , API:
46
6.2
3.0
class PoetryClientFactory(ClientFactory):
protocol = PoetryProtocol
def __init__(self, callback):
self.callback = callback
def poem_finished(self, poem):
self.callback(poem)
, factory , 2.1,
.
, . PoetryProtocol ,
2.1:
class PoetryProtocol(Protocol):
poem = ''
def dataReceived(self, data):
self.poem += data
def connectionLost(self, reason):
self.poemReceived(self.poem)
def poemReceived(self, poem):
self.factory.poem_finished(poem)
, get_poetry PoetryClientFactory
PoetryProtocol .
. main :
def poetry_main():
addresses = parse_args()
from twisted.internet import reactor
poems = []
47
def got_poem(poem):
poems.append(poem)
if len(poems) == len(addresses):
reactor.stop()
for address in addresses:
host, port = address
get_poetry(host, port, got_poem)
reactor.run()
for poem in poems:
print poem
, ,
, ( ,
Twisted).
, 3.0, . ,
, .
6.3
callback' ,
11:
. 11: callback'
11 .
48
...
import poetrylib # I just made this module name up
poem = poetrylib.get_poetry(host, port)
...
. , ,
, , . ,
Twisted get_poetry, , callback'. ,
, .
, - .
. , import . :
.
Twisted ,
Twisted ,
. Twisted -
49
, ,
.
, , ,
Twisted . Twisted
pyGTK pyQT, python API
GUI .
6.4
3.0 ,
, 1.0. 3.0
, ,
, . clientConnectionFailed
, ClientFactory
. callback
got_poem, reactor
, , 2.
, , ?
Factory clientConnectionFailed,
. , Factory , -
, Factory . ,
( ? ). - .
, get_poetry ,
, , . , get_poetry
try/except. , . ,
,
get_poetry. :
"""
callback' (, poem is None),
.
, , .
, None - . API None
. -, None .
, , traceback,
. , :
51
twisted-failure/failure-examples.py ,
Failure. Failures
traceback' ,
except.
Failure. 7 ,
Twisted .
, :
try:
attempt_to_do_something_with_poetry()
except RhymeSchemeViolation:
# the code path when things go wrong
else:
# the code path when things go so, so right baby
,
.
callback:
6.5
3.1
API ,
. 3.1 twisted-client3/get-poetry-1.py. . PoetryClientFactory : callback errback, clientConnectionFailed:
class PoetryClientFactory(ClientFactory):
protocol = PoetryProtocol
def __init__(self, callback, errback):
self.callback = callback
self.errback = errback
def poem_finished(self, poem):
self.callback(poem)
def clientConnectionFailed(self, connector, reason):
self.errback(reason)
clientConnectionFailed Failure ( reason), ,
errback.
,
. 3.1, :
Poem failed: [Failure instance: Traceback (failure with no frames): : Connection was refused by other side: 111: Conn
]
print poem_failed errback'.
Twisted ,
traceback. traceback
, , Twisted
, .
6.6
API, Twisted , .
53
, callback' ,
Twisted.
callback'.
, API, Twisted
, callback errback?
. , Twisted ,
, .
.
6.7
1. 3.1 timeout, , .
errback .
.
2. trap Failure. except
try/except.
3. print , , clientConnectionFailed
get_poetry.
54
7.1
6 , callback'
Twisted. Twisted ,
. ,
Twisted , ,
: , .
, API get_poetry,
callback' ( callback'): -
, - . Twisted ,
callback',
, , callback',
.
, Twisted get_poetry 3.1:
...
def got_poem(poem):
print poem
reactor.stop()
def poem_failed(err):
print >>sys.stderr, 'poem download failed'
print >>sys.stderr, 'I am terribly sorry'
print >>sys.stderr, 'try again later?'
reactor.stop()
get_poetry(host, port, got_poem, poem_failed)
reactor.run()
:
1. - .
2. - .
3. .
:
...
try:
poem = get_poetry(host, port) # the synchronous version of get_poetry
except Exception, err:
55
56
, callback
errback. , - .
callback errback callback 27 .
get_poetry.
else except try/except, , callback,
errback
get_poetry. , - .
, callback'
errback'. ? , , callback' errback' ,
get_poetry,
.
: . reactor.stop
sys.exit.
:
...
try:
poem = get_poetry(host, port) # the synchronous version of get_poetry
except Exception, err:
print >>sys.stderr, 'poem download failed'
print >>sys.stderr, 'I am terribly sorry'
print >>sys.stderr, 'try again later?'
else:
print poem
sys.exit()
?
, , callback errback -
. callback',
?
, ,
callback':
1. errback' . errback' except, .
API.
2. callback'
. , callback errback .
3. callback'.
57
callback' ,
, Twisted .
7.2
Deferred
callback' , , ,
, Twisted , Deered, , callback'. Deferred twisted.internet.defer.
"deferred"() - ,
,
. , , "deferred
Deferred. , Deferred
. "" ,
" ". , .
deferred callback : , - . deferred
. , callback'
errback', deferred
( !) ( ,
). deferred callback', errback' , .
12 Deered callback errback :
58
. 12: Deferred
. deferred' reactor,
, .
, setTimeout Deferred reactor. , , ,
. , .
twisted-deferred/defer-1.py:
. , :
1. callback/errback, 3.1, callback', deferred',
, .
, deferred' callback' errback'
,
: .
2. callback' errback' deferred .
3. callback deferred ,
.
4. print', , deferred' callback' .
, reactor .
Python'.
, . twisted-deferred/defer2.py errback deferred':
60
. callback', errback' .
Failure errback
, 3.1. , deferred
Exception Failure.
twisted-deferred/defer-3.py:
twisted.python.failure.Failure
[Failure instance: Traceback (failure with no frames): : I have failed.
]
No poetry for you.
, deferred', ,
Failure . deferred ,
errback Failure.
callback, errback. , . ,
callback errback. , : , - . twisted-deferred/defer-4.py:
First result
Traceback (most recent call last):
...
twisted.internet.defer.AlreadyCalledError
! deferred . , deferred , :
twisted-deferred/defer-4.py
twisted-deferred/defer-5.py
twisted-deferred/defer-6.py
twisted-deferred/defer-7.py
import sys
from twisted.internet.defer import Deferred
def got_poem(poem):
print poem
from twisted.internet import reactor
reactor.stop()
def poem_failed(err):
print >>sys.stderr, 'poem download failed'
print >>sys.stderr, 'I am terribly sorry'
print >>sys.stderr, 'try again later?'
from twisted.internet import reactor
reactor.stop()
d = Deferred()
d.addCallbacks(got_poem, poem_failed)
62
import sys
from twisted.internet.defer import Deferred
def got_poem(poem):
print poem
def poem_failed(err):
print >>sys.stderr, 'poem download failed'
print >>sys.stderr, 'I am terribly sorry'
print >>sys.stderr, 'try again later?'
def poem_done(_):
from twisted.internet import reactor
reactor.stop()
d = Deferred()
d.addCallbacks(got_poem, poem_failed)
d.addBoth(poem_done)
from twisted.internet import reactor
reactor.callWhenRunning(d.callback, 'Another short poem.')
reactor.run()
addBoth callback
errback. , , .
: , deferred errback .
, , deferred'.
63
7.3
callback' .
, Deferred
:
1. errback',
API. Deferred' errback'.
2. callback' , . Deferred'
,
try/except.
3. callback' . deferred', ,
.
deferred', .
,
, .
7.4
1. poem_done.
. , got_poem poem_done.
2. deferred'
errback . , errback Exception.
3. addCallback
addErrback Deferred.
64
8.1
4.0
, - deferred',
Twisted . 4.0 twisted-client-4/get-poetry.py.
get_poetry callback
errback. deferred, callback' errback'.
class PoetryClientFactory(ClientFactory):
protocol = PoetryProtocol
def __init__(self, deferred):
self.deferred = deferred
def poem_finished(self, poem):
if self.deferred is not None:
d, self.deferred = self.deferred, None
d.callback(poem)
def clientConnectionFailed(self, connector, reason):
if self.deferred is not None:
d, self.deferred = self.deferred, None
d.errback(reason)
, deferred
.
Twisted, , deferred .
Python'.
, PoetryProtocol, .
, - poetry_main:
65
def poetry_main():
addresses = parse_args()
from twisted.internet import reactor
poems = []
errors = []
def got_poem(poem):
poems.append(poem)
def poem_failed(err):
print >>sys.stderr, 'Poem failed:', err
errors.append(err)
def poem_done(_):
if len(poems) + len(errors) == len(addresses):
reactor.stop()
for address in addresses:
host, port = address
d = get_poetry(host, port)
d.addCallbacks(got_poem, poem_failed)
d.addBoth(poem_done)
reactor.run()
for poem in poems:
print poem
, deferred' poem_done callback' errback'.
deferred' Twisted, d deferred, . , ,
"deferred".
8.2
get_poetry
, : . , deferred. deferred -
API Twisted ,
Twited, deferred':
Deferred " " " ".
13:
66
deferred, API :
. . ,
, callback' deferred'
. , - ,
errback deferred'.
,
deferred, . ,
, deferred'.
deferred' - " "
. deferred,
, - , , , .
deferred ,
deferred' , . , deferred'.
deferred' ( , Twisted),
deferred' API,
Twisted .
deferred', Twisted Twisted ,
callback', , , .
67
8.3
deferred', callback',
Twisted, deferred', . , ,
deferred', . , , , os.system Twisted deferred
addCallback.
, Twisted
.
Twsisted deferred',
reactor, , deferred' .
, , . Twisted ,
, reactor. Deferred' - ,
Twisted
.
stack trace , callback. twisted-client-4/get-poetrystack.py . :
68
69
2. reactor, callback' - .
3. .
4. callback , .
callback' deferred' .
, callback, , , deferred'. deferred (d.callback), . , :
Deferred' - ( Twisted) callback'.
callback', callback' .
deferred'
callback'. twisted-deferred/deferblock.py. callback , time.sleep. print,
, callback ,
deferred'.
8.4
70
8.5
1. 4.0 timeout', ,
.
errback deferred', . .
2. 4.1 ,
, . , keyword-,
callback' errback'.
71
Deferred',
9.1
callback'
, callback'. deferred', ,
Twisted, Deferred
, .
callback'. , deferred' .
, . ,
, : Byronication
Engine.
, , .
, Python' :
class IByronificationEngine(Interface):
def byronificate(poem):
"""
Return a new poem like the original, but in the style of Lord Byron.
Raises GibberishError if the input is not a genuine poem.
"""
, . , , byronicate ,
, .
,
, ,
. ,
:
1. .
2. - , , .
3. ,
Byronication.
72
4. GibberishError, , .
5. - , .
6. - .
7. .
, GibberishError ,
, , .
, : . ,
- , , . , - , ,
" ".
:
try:
poem = get_poetry(host, port) # synchronous get_poetry
except:
print >>sys.stderr, 'The poem download failed.'
else:
try:
poem = engine.byronificate(poem)
except GibberishError:
print >>sys.stderr, 'The poem download failed.'
except:
print poem # handle other exceptions by using the original poem
else:
print poem
sys.exit()
, .
( deferred'), .
. , , ,
3.1, ,
deferred'. . , got_poem
callback :
def got_poem(poem):
poems.append(byron_engine.byronificate(poem))
poem_done()
73
, byronicate GibberishError
- ? 11, :
1. callback' poem_nished factory,
, callback.
2. poem_nished ,
poemReceived .
3. connectionLost .
4. Twised, .
, reactor , . , -
, . reactor
GibberishError, ,
.
, , , . got_poem
.
,
.
15, , :
. 15: C
main - " ,
, ,
74
. , main ,
, ,
(, , , - ).
, connect socket, "".
- , . , ,
. connect - , , ,
.
get_poetry . ,
( , ), ,
, .
, , connect', ,
, ,
, , - (
Python' ).
,
, , "
". " " " .
75
3.1 .
, , 16, :
. 16: callback'
: callback', (reactor)
,
. , ,
stack frame', , , , . ,
, ,
, .
Twisted , . , ( reactor
). , callback' ( deferred'),
, Twisted,
, - . ,
!
,
callback, , try/except ,
, . errback', ,
.
.
76
9.2
Deferred'
77
). ,
deferred.
2. 0, callback/errback, , deferred. deferred callback,
callback 0. deferred
errback, errback 0.
3. N , errback N+1 ( Failure)
.
4. N , callback
N+1 , N+1,
.
17:
. 17: deferred'
, , callback errback
, , .
. 17 ,
deferred ,
. 18
"":
78
. 18: deferred'
79
Finished
Unhandled error in Deferred:
Traceback (most recent call last):
...
--- <exception caught here> --...
exceptions.Exception: oops
:
1. print , .
2. , traceback , .
3. traceback' , deferred .
4. "Unhandled" "Finished".
, deferred', callback' , (, , deferred' ). , "Finish"
, "Unhandled"
, deferred . .
"",
raise . , , ,
.
, errback'. deferred
, callback/errback , :
callback/errback ,
callback/errback Failure.
80
9.3
Callback' Errback',
- , ,
callback' errback' deferred, , .
- , deferred' callback' errback' .
4 Deered,
:
1. addCallbacks
2. addCallback
3. addErrback
4. addBoth
, . callback/errback. addCallback callback (,
) ""errback. - , .
errback' Failure, errback
errback'
.
, addErrback errback callback.
callback' Failure, callback
callback' .
9.4
Deferred
, deferred'
callback' errback'. twisted-deferred/deferred-simulator.py
python , "deferred , , deferred'
. ,
callback/errback . callback' errback'
:
( )
( )
81
( )
, , ,
,
callback errback.
, , , , . narrow ,
.
, callback ,
, - .
, ,
callback' errback'.
9.5
callback', , callback
, , callback'
. Deferred ,
, , reactor.
, ( ) .
, -,
deferred callback errback , .
, .
9.6
1. Deferred,
callback' errback'. , callback/errback.
2. deferred ,
:
deferred.addCallbacks(my_callback, my_errback)
82
deferred.addCallback(my_callback)
deferred.addErrback(my_errback)
,
.
83
10
10.1
5.0
, 9, - Cummingsier. Cummingsier
- ,
e.e.cummings. , o:
def cummingsify(poem):
return poem.lower()
, , , 5.0,
twisted-client-5/get-poetry.py,
cummingsify, :
1.
2. GibberishError
3. ValueError
, .
5.0 poetry_main:
def poetry_main():
addresses = parse_args()
from twisted.internet import reactor
poems = []
errors = []
def try_to_cummingsify(poem):
try:
return cummingsify(poem)
except GibberishError:
raise
except:
print 'Cummingsify failed!'
return poem
def got_poem(poem):
print poem
poems.append(poem)
def poem_failed(err):
print >>sys.stderr, 'The poem download failed.'
errors.append(err)
84
def poem_done(_):
if len(poems) + len(errors) == len(addresses):
reactor.stop()
for address in addresses:
host, port = address
d = get_poetry(host, port)
d.addCallback(try_to_cummingsify)
d.addCallbacks(got_poem, poem_failed)
d.addBoth(poem_done)
reactor.run()
, c ,
:
1.
2. Cummingsify failed!
3. The poem download failed.
,
5.0,
,
. ,
.
callback/errback,
Deferred', get_poetry:
85
, pass-through errback
addCallback. pass-through Failure errback' (poem_failed). , poem_failed :
get_poetry ( deferred poem_failed deferred' errback) cummingsify.
, 19
Inkscape .
, deferred'. ,
cummingsify , 20:
, callback' ,
callback. ,
poem_done None , got_poem
. , callback ,
got_poem , .
21 , ,
cummingsify GibberishError:
try_to_cummingsify callback
GibberishError, errback
poem_failed
(, Failure).
http://inkscape.org/
86
. 21: , GibberishError
, poem_failed ,
Failure, , , callback. , poem_failed
, None - . , , poem_failed , ,
poem_failed , err ,
errback.
, got_poem, poem_failed , poem_done errback
. , errback,
,
got_poem, poem_failed ,
. addBoth ,
deferred (
), addBoth nally try/except.
, 22,
, cummingsify
ValueError.
20, ,
got_poem . callback'
try_to_cummingsify, ValueError try/except .
87
. 22: , cummingsify
deferred .
, 23 - , :
. 23: ,
, poem_failed None,
callback.
88
10.2
5.1
def poetry_main():
addresses = parse_args()
from twisted.internet import reactor
poems = []
errors = []
def cummingsify_failed(err):
if err.check(CannotCummingsify):
print 'Cummingsify failed!'
return err.value.args[0]
return err
def got_poem(poem):
print poem
poems.append(poem)
89
def poem_failed(err):
print >>sys.stderr, 'The poem download failed.'
errors.append(err)
def poem_done(_):
if len(poems) + len(errors) == len(addresses):
reactor.stop()
for address in addresses:
host, port = address
d = get_poetry(host, port)
d.addCallback(cummingsify)
d.addErrback(cummingsify_failed)
d.addCallbacks(got_poem, poem_failed)
d.addBoth(poem_done)
deferred 24:
cummingsify_failed errback:
def cummingsify_failed(err):
if err.check(CannotCummingsify):
print 'Cummingsify failed!'
return err.value.args[0]
return err
check Failure , Failure CannotCummingsify.
90
, ( ) , . Failure,
callback. , Failure
errback. , Failure.
25 ,
CannotCummingsify:
. 25: CannotCummingsify
, deferred',
try/except deferred' errback.
10.3
10 , Deferred
callback' errback'. ,
deferred' callback errback
.
91
, deferred', ?
! deferred' . , , 11,
Twisted .
10.4
1. 25 deferred' 5.1. .
2. deferred simulator
5.0 5.1. , , try_to_cummingsify 5.0:
r poem p
r None r None
r None r None
92
11
11.1
Twisted
c Twisted,
Twisted. Twisted, , ,
. ,
Twisted, twisted-server-1/fastpoetry.py.
fastpoetry,
, , . , , !
. ,
PoetryProtocol:
class PoetryProtocol(Protocol):
def connectionMade(self):
self.transport.write(self.factory.poem)
self.transport.loseConnection()
, Protocol
( , , ). ,
Protocol
. , ,
, connectionMade, callback'
Protocol Transport.
Transport :
(self.transport.write)
(self.transport.loseConnection). , .
, write()
, loseConnection()
, ,
, .
, Protocol Factory,
, :
class PoetryFactory(ServerFactory):
protocol = PoetryProtocol
def __init__(self, poem):
self.poem = poem
93
. Factory, PoetryProtocol , ,
PoetryProtocol .
, ServerFactory ClientFactory.
, ,
ClientFactory. ? listenTCP,
, factory
ServerFactory.
main, listenTCP:
def main():
options, poetry_file = parse_args()
poem = open(poetry_file).read()
factory = PoetryFactory(poem)
from twisted.internet import reactor
port = reactor.listenTCP(options.port or 0, factory,
interface=options.iface)
print 'Serving %s on %s.' % (poetry_file, port.getHost())
reactor.run()
:
1. ,
2. PoetryFactory
3. listenTCP , Twisted,
, Factory Protocol
.
, , - .
( netcat), , .
11.2
8 9 5.
Protocol
94
95
. 26:
. , ,
- .
, Twisted , .
, , - , ,
, .
- .
Twisted , . , Twisted
( Factory- listenTCP
). , , ,
Twisted , .
, .
, ,
. ,
, ,
Ctrl-C ( ). , , 12,
, .
96
11.3
1. Twisted,
, 2. , , ,
.
2. Twisted, callLater
LoopingCall, transport.write().
--num-bytes --delay , -
. ,
, .
3. Twisted , ( ).
4.
Twisted ? ?
97
12
12.1
, Twisted , , Deferred'.
9 10 ,
. (cummingsier) , ,
, ,
. , ,
, , .
, 12
, , ,
, ,
,
Deferred'.
12.2
. ,
. ,
- ,
.
. :
. , : . , (Remote Procedure Call).
Twisted ,
, XML-RPC,
Perspective Broker AMP.
, , . ,
( ):
98
. netstring.
, netstring. netstring' ,
, , (,
). , .
, ,
.
12.3
, twisted-server-1/tranformedpoetry.py. TransformService:
class TransformService(object):
def cummingsify(self, poem):
return poem.lower()
- cummingsify, .
. :
, .
- Twisted.
.
protocol factory (
):
class TransformFactory(ServerFactory):
protocol = TransformProtocol
def __init__(self, service):
self.service = service
def transform(self, xform_name, poem):
thunk = getattr(self, 'xform_%s' % (xform_name,), None)
if thunk is None: # no such transform
return None
99
try:
return thunk(poem)
except:
return None # transform failed
def xform_cummingsify(self, poem):
return self.service.cummingsify(poem)
factory transform, protocol
. None,
,
. , TransformService, protocol factory
,
protocol.
: , xform_. , Twisted, . ,
. API, .
:
class TransformProtocol(NetstringReceiver):
def stringReceived(self, request):
if '.' not in request: # bad request
self.transport.loseConnection()
return
xform_name, poem = request.split('.', 1)
self.xformRequestReceived(xform_name, poem)
def xformRequestReceived(self, xform_name, poem):
new_poem = self.factory.transform(xform_name, poem)
if new_poem is not None:
self.sendString(new_poem)
self.transport.loseConnection()
, Twisted
netstring' NetstringReceiver.
netstring', , , - stringReceived. stringReceived
netstring', ,
, netstring ( ).
100
NetstringReceiver .
( ), ,
sendString, NetstringReceiver ( transport.write()). main,
.
, Twisted , ,
xformRequestReceived,
: .
12.4
Twisted , ,
twisted-server-1/transform-test. netcat,
( netstring). ,
11000:
./twisted-server-1/transform-test 11000
:
15:here is my poem,
netstring ( ).
12.5
:
1.
2. , Twisted
3.
101
.
; , . ,
. , .
, - Twisted.
twisted.protocols.basic . -
Twisted, , ,
, , .
, , - Service ,
Twisted. , , ,
, .
Service , .
27 , ( , ):
protocol factory,
27,
protocol . (factory)
Service, Protocol
.
12.6
13, , .
102
. 27:
12.7
103
13
13.1
Deferred' Deferred'
104
. 28: deferred'
callback/errback deferred). ,
, deferred deferred,
callback . ,
deferred deferred. , deferred ,
deferred', .
, deferred () deferred'.
, , callback deferred
28 , . ,
deferred
callback , .
29 deferred', 28, .
Deered, , , . , twisteddeferred/defer-10.py. deferred': -
105
29:
deferred'
13.2
6.0
class TransformClientProtocol(NetstringReceiver):
106
def connectionMade(self):
self.sendRequest(self.factory.xform_name, self.factory.poem)
def sendRequest(self, xform_name, poem):
self.sendString(xform_name + '.' + poem)
def stringReceived(self, s):
self.transport.loseConnection()
self.poemReceived(s)
def poemReceived(self, poem):
self.factory.handlePoem(poem)
NetstringReceiver
. , ,
TransformClientFactory. , , factory .
TransformClientFactory:
class TransformClientFactory(ClientFactory):
protocol = TransformClientProtocol
def __init__(self, xform_name, poem):
self.xform_name = xform_name
self.poem = poem
self.deferred = defer.Deferred()
def handlePoem(self, poem):
d, self.deferred = self.deferred, None
d.callback(poem)
def clientConnectionLost(self, _, reason):
if self.deferred is not None:
d, self.deferred = self.deferred, None
d.errback(reason)
clientConnectionFailed = clientConnectionLost
factory ,
Protocol'. Factory Deferred, . ,
TransformClientFactory : , .
, clientConnectionLost , , ,
self.deferred None, handlePoem.
TransformClientFactory Deferred, . Twisted , :
107
, Deferred,
Deferred'.
- ,
deferred ,
Twisted .
TransformClientFactory, Proxy, TCP :
class TransformProxy(object):
"""
I proxy requests to a transformation service.
"""
def __init__(self, host, port):
self.host = host
self.port = port
def xform(self, xform_name, poem):
factory = TransformClientFactory(xform_name, poem)
from twisted.internet import reactor
reactor.connectTCP(self.host, self.port, factory)
return factory.deferred
xform(),
. deferred, .
, try_to_cummingsify
callback':
def try_to_cummingsify(poem):
d = proxy.xform('cummingsify', poem)
def fail(err):
print >>sys.stderr, 'Cummingsify failed!'
return poem
return d.addErrback(fail)
callback deferred,
Proxy .
try_to_cummingsify deferred' ( get_poetry), ,
.
, d.addErrback(fail).
. addCallback addErrback
deferred.
:
d.addErrback(fail)
return d
108
13.3
. , 10001, ,
10002 10003, :
13.4
, deferred'
deferred' callback-, , callback' deferred'
. ,
, , .
deferred'? !
, 14.
13.5
1. , .
2. ,
. , .
3. PoetryClientFactory deferred'
- . get_poetry PoetryClientFactory
, .
109
110
14
14.1
, Deferred Deferred'
Deered.
, . ,
,
. .
, .
.
, , ,
. , . 30:
. 30:
,
. , () , .
, , deferred. ,
111
, .
, - .
, ,
? Twisted ,
Deferred, : deferred , , .
, deferred , callback' errback' deferred ,
. , deferred ,
. , :
deferred callback (
errback, deferred') , , .
31, deferred, :
. 31: deferred
callback/errback ,
deferred callback,
32.
callback ( errback) , callback . ( Exception Failure),
errback.
112
,
twisted-deferred/defer-11.py. ,
, deferred ,
callback'. , callback ( ,
print).
, , pause(), deferred , callback'
. callback', unpause(). ,
deferred' , callback' deferred.
14.2
1.0
twisted-server-1/poetry-proxy.py.
, , Protocol/Factory ,
, - . , .
,
ProxyService,
:
113
class ProxyService(object):
poem = None # the cached poem
def __init__(self, host, port):
self.host = host
self.port = port
def get_poem(self):
if self.poem is not None:
print 'Using cached poem.'
return self.poem
print 'Fetching poem from server.'
factory = PoetryClientFactory()
factory.deferred.addCallback(self.set_poem)
from twisted.internet import reactor
reactor.connectTCP(self.host, self.port, factory)
return factory.deferred
def set_poem(self, poem):
self.poem = poem
return poem
- get_poem. ,
. ,
, deferred, , .
get_poem - , .
, ? protocol/factory :
class PoetryProxyProtocol(Protocol):
def connectionMade(self):
d = maybeDeferred(self.factory.service.get_poem)
d.addCallback(self.transport.write)
d.addBoth(lambda r: self.transport.loseConnection())
class PoetryProxyFactory(ServerFactory):
protocol = PoetryProxyProtocol
def __init__(self, service):
self.service = service
PoetryProxyFactory :
, PoetryProxyProtocol
get_poem. PoetryProxyFactory - , . get_poem , PoetryProxyFactory twisted.internet.defer maybeDeferred.
maybeDeferred , ( ). maybeDeferred :
114
deferred, maybeDeferred
deferred
, maybeDeferred
deferred', ,
, deferred. ( ,
) , deered.
1: , . deferred, , , callback'
errback', , , .
2: , , ,
deferred, maybeDeferred -
.
PoetryProxyProtocol deferred , callback',
.
14.3
, , :
115
14.4
2.0
def get_poem(self):
if self.poem is not None:
print 'Using cached poem.'
# return an already-fired deferred
return succeed(self.poem)
print 'Fetching poem from server.'
factory = PoetryClientFactory()
factory.deferred.addCallback(self.set_poem)
from twisted.internet import reactor
reactor.connectTCP(self.host, self.port, factory)
return factory.deferred
defer.succeed - deferred . , , , ,
deferred' .callback().
deferred , defer.fail.
116
, get_poem deferred,
PoetryProxyProtocol maybeDeferred
(, , , , ):
class PoetryProxyProtocol(Protocol):
def connectionMade(self):
d = self.factory.service.get_poem()
d.addCallback(self.transport.write)
d.addBoth(lambda r: self.transport.loseConnection())
,
, .
14.5
deferred'
, , ( ) .
:
maybeDeferred ,
deferred, -
( );
- . , ,
. , .
, callback'
errback' deferred', .
, 9,
twisted-deferred/defer-unhandled.py. , deferred' , callback
errback ,
, deferred (,
). :
117
14.6
118
. , .errback() deferred' .
4. -. , ,
, .
5. :
d = some_async_function() # d is a Deferred
d.addCallback(my_callback)
d.addCallback(my_other_callback)
d.addErrback(my_errback)
, deferred d 1,
. deferred',
, callback'
errback' 2-4? ?
119
15
15.1
, Twisted,
. :
,
unittest Python'? : .
, ,
.
, Twisted , trial,
( ).
, unittest ,
( TestCase), , test, .
,
setUp tearDown, .
15.2
tests/test_poetry.py . ( PYTHONPATH)
test. ,
, ,
.
,
. , , setUp
testcase':
class PoetryTestCase(TestCase):
def setUp(self):
factory = PoetryServerFactory(TEST_POEM)
from twisted.internet import reactor
self.port = reactor.listenTCP(0, factory, interface="127.0.0.1")
self.portnum = self.port.getHost().port
setUp ,
. ,
. , ,
tearDown, :
120
def tearDown(self):
port, self.port = self.port, None
return port.stopListening()
test_client get_poetry ,
, ,
, :
def test_client(self):
"""The correct poem is returned by get_poetry."""
d = get_poetry('127.0.0.1', self.portnum)
def got_poem(poem):
self.assertEquals(poem, TEST_POEM)
d.addCallback(got_poem)
return d
def test_failure(self):
"""The correct failure is returned by get_poetry when
connecting to a port with no server."""
d = get_poetry('127.0.0.1', -1)
return self.assertFailure(d, ConnectionRefusedError)
assertFailure trial'.
assertRaises unittest, . deferred, ,
deferred , - .
121
, trial
:
trial tests/test_poetry.py
, testcase
OK, , .
15.3
. 33: trial
122
- ,
, , deferred'.
trial - . ,
( ) , :
1.
2. , deferred
,
deferred ( , deferred).
. , , trial, , deferred'.
15.4
15.5
1. , ,
trial , .
2. Twisted .
3. .
4. Twisted .
1
2
http://twistedmatrix.com/documents/current/core/howto/testing.html
http://twistedmatrix.com/trac/browser/trunk/twisted/test
123
16
Twisted
16.1
, , , print.
, . , , :
1. ,
. , .
2. syslog.
3. , , .
4. pid ,
.
, twistd,
Twisted. , .
16.2
16.2.1
IService
IService ,
.
.
: name running.
name - , 'fastpoetry', None,
. running - , true, .
IService. , , ,
124
def startService():
"""
Start the service.
"""
def stopService():
"""
Stop the service.
@rtype: L{Deferred}
@return: a L{Deferred} which is triggered when the service has
finished shutting down. If shutting down is immediate, a
value can be returned (usually, C{None}).
"""
. ,
startService :
stopService :
, . ,
, Twisted ,
.
, stopService deferred, , . . ,
None deferred'.
125
, . IService,
- setServiceParent, Service :
def setServiceParent(parent):
"""
Set the parent of the service.
@type parent: L{IServiceCollection}
@raise RuntimeError: Raised if the service already has a parent
or if the service has a name and the parent already has a child
by that name.
"""
, ,
.
Interface', .
16.2.2
IServiceCollection
(getServiceNamed)
(__iter__)
(addService)
(removeService)
, IServiceCollection IService,
( ).
16.2.3
Application
Twisted Application . ,
Application IService IServiceCollection,
, .
- , Twisted . ( , ..) Application.
126
, Application. Twisted
, .
16.2.4
Twisted
16.3
FastPoetry 2.0
, . , twistd.
twisted-server-3/fastpoetry.py.
PoetryProtocol:
class PoetryProtocol(Protocol):
def connectionMade(self):
poem = self.factory.service.poem
log.msg('sending %d bytes of poetry to %s'
% (len(poem), self.transport.getPeer()))
self.transport.write(poem)
self.transport.loseConnection()
, print,
twisted.python.log.msg .
PoetryFactory:
class PoetryFactory(ServerFactory):
protocol = PoetryProtocol
def __init__(self, service):
self.service = service
, PoetryFactory,
,
PoetryFactory. , PoetryProtocol service
factory. , :
127
class PoetryService(service.Service):
def __init__(self, poetry_file):
self.poetry_file = poetry_file
def startService(self):
service.Service.startService(self)
self.poem = open(self.poetry_file).read()
log.msg('loaded a poem from: %s' % (self.poetry_file,))
Interface, Twisted
, ,
. twisted.application.service.Service
PoetryService.
, . , startService
. ,
( running).
. PoetryService
PoetryProtocol. ,
. , PoetryService ,
TCP . ,
, UDP XML-RPC.
, .
Twisted , ,
, (, fastpoetry.protocol fastpoetry.service).
, , .
16.3.1
Twisted tac
,
Twisted tac . tac - Twisted Application Conguration ,
twistd . , (
, ..)
. , tac (
128
), .
, tac ( tac
). , tac poetry/ecstasy.txt
10000 loopback :
# configuration parameters
port = 10000
iface = 'localhost'
poetry_file = 'poetry/ecstasy.txt'
, twistd , ,
. , twistd , .
:
# this will hold the services that combine to form the poetry server
top_service = service.MultiService()
: PoetryService, , Twisted , , .
, , MultiService -
Twisted, IService IServiceCollection.
, MultiService . , MultiService
, MultiService , , .
:
# the poetry service holds the poem. it will load the poem when it is
# started
poetry_service = PoetryService(poetry_file)
poetry_service.setServiceParent(top_service)
. PoetryService
, setServiceParent,
Twisted. TCP :
Twisted TCPServer
TCP , factory ( PoetryFactory). reactor.listenTCP ,
tac - . TCPServer ,
twistd.
, . , - , ,
.
,
.
, , . Application
:
16.3.2
. - tac ,
twistd. , tac Python . tac twistd,
Python , :
python twisted-server-3/fastpoetry.py
, , !
, tac -
, . tac ,
.tac .py. twistd .
-, twistd:
130
. 34: fastpoetry
2010-06-23
2010-06-23
2010-06-23
2010-06-23
2010-06-23
2010-06-23
20:57:14-0700
20:57:14-0700
20:57:14-0700
20:57:14-0700
20:57:14-0700
20:57:14-0700
[-]
[-]
[-]
[-]
[-]
[-]
Log opened.
twistd 10.0.0 (/usr/bin/python 2.6.5) starting up.
reactor class: twisted.internet.selectreactor.SelectReactor.
__builtin__.PoetryFactory starting on 10000
Starting factory <__builtin__.PoetryFactory instance at 0x14ae8c0>
loaded a poem from: poetry/ecstasy.txt
:
1. Twisted,
log.msg PoetryFactory. logger tac
, twistd .
2. , , PoetryService
TCPServer, .
3. . ,
. , twistd
( twistd),
nodaemon, twistd
, . tac .
netcat':
131
16.3.3
,
, twistd :
132
. ,
twistd.pid, , , twistd.log,
, .
, twistd ,
. -
twistd.log, ,
twistd, , ,
--logle. , twistd ,
.
, . ,
.
.
( , init), Ctrl-C. , , .
twistd.pid,
:
16.4
Twisted
, twistd . , ,
Python', . ,
. ,
:
1.
133
2.
3.
tac
. Twisted
.
Twisted , twistd . Twisted . , twisted .
twisted-intro. , :
...
ftp
telnet
socks
...
An FTP server.
A simple, telnet-based remote debugging service.
A SOCKSv4 proxy service.
Twisted.
, twistd.
, , help. ,
ftp:
--nodaemon
, , ,
. ,
Ctrl-C.
Ok, Twisted .
, .
134
16.4.1
IPlugin
Twisted twisted.plugin.IPlugin.
, , . IPlugin - , , - ! , twistd
. , ,
,
.
, , c ? zope.interface ,
, . plugin-
.
16.4.2
IServiceMaker
IPlugin,
IServiceMaker. , IServiceMaker, IService,
application. IServiceMaker :
1. tapname: . tap
Twisted Application Plugin. , Twisted pickled application les, taples, .
2. description: , twistd
help .
3. options: , , .
4. makeService: , IService .
,
.
16.5
135
,
. twistd ,
twisted/plugins ( __init__.py );
twisted/plugins PYTHONPATH, twisted . , , , ,
, .
protocol, factory
service , tac . ,
, ,
, .
:
class Options(usage.Options):
optParameters = [
['port', 'p', 10000, 'The port number to listen on.'],
['poem', None, None, 'The file containing the poem.'],
['iface', None, 'localhost', 'The interface to listen on.'],
]
, ,
twistd. , . , PoetryServiceMaker:
class PoetryServiceMaker(object):
implements(service.IServiceMaker, IPlugin)
tapname = "fastpoetry"
description = "A fast poetry service."
options = Options
def makeService(self, options):
top_service = service.MultiService()
poetry_service = PoetryService(options['poem'])
poetry_service.setServiceParent(top_service)
factory = PoetryFactory(poetry_service)
tcp_service = internet.TCPServer(int(options['port']), factory,
interface=options['iface'])
tcp_service.setServiceParent(top_service)
return top_service
zope.interface.implements , IServiceMaker
136
IPlugin. , Application,
,
application, twistd . , options ,
, , twistd.
, ,
:
service_maker = PoetryServiceMaker()
twistd
. tac , name, , . ,
IPlugin IServiceMaker.
, , .
, twisted-intro ,
PYTHONPATH. ,
twistd. , fastpoetry
.
, dropin.cache twisted/plugins. twistd .
:
137
16.6
, Twisted . Twisted
twistd Twisted , tac , Twisted . 17
callback' Twisted.
16.7
1. tac
. ,
MultiService.
2. tac ,
.
3. plugin , , .
4. .
138
17
17.1
callback'
callback'.
callback' Twisted, .
x Deferred'. ,
, . , ,
, , callback'.
17.1.1
, Python' -
, yield .
, , , . ,
yield.
( )
.
inline-callbacks/gen-1.py:
def my_generator():
print 'starting up'
yield 1
print "workin'"
yield 2
print "still workin'"
yield 3
print 'done'
for n in my_generator():
print n
, 1,
2, 3. , , print
, print ,
.
(inline-callbacks/gen-2.py):
def my_generator():
print 'starting up'
yield 1
139
print
yield
print
yield
print
"workin'"
2
"still workin'"
3
'done'
gen = my_generator()
while True:
try:
n = gen.next()
except StopIteration:
break
else:
print n
. :
1. - , ( next).
2. ,
( yield).
3. ( print ), .
4. , (,
).
5. , (
) , .
, callback' . , while - reactor, callback', yield, ,
callback' ,
callback'.
, ( inline-callbacks/gen-3.py), callback', , , Twisted.
, - . Callback' , . deferred',
140
callback , Python ,
Failure.
Python 2.5, , , ; inline-callbacks/gen-4.py :
class Malfunction(Exception):
pass
def my_generator():
print 'starting up'
val = yield 1
print 'got:', val
val = yield 2
print 'got:', val
try:
yield 3
except Malfunction:
print 'malfunction!'
yield 4
print 'done'
gen = my_generator()
print
print
print
print
try:
gen.next()
except StopIteration:
pass
Python 2.5 , yield - ,
. , ,
, send next ( next,
- None). ,
, throw. .
17.2
callback'
,
, callback', callback' deferred',
, . callback' yield'
yield - callback'
141
( yield ). 35 :
. 35: callback'
142
17.2.1
inlineCallbacks
inline-callbacks/inline-callbacks-1.py:
143
17.3
7.0
inlineCallbacks
. twisted-client-7/get-poetry.py.
6.0 twisted-client-6/get-poetry.py. poetry_main:
def poetry_main():
addresses = parse_args()
144
xform_addr = addresses.pop(0)
proxy = TransformProxy(*xform_addr)
from twisted.internet import reactor
results = []
@defer.inlineCallbacks
def get_transformed_poem(host, port):
try:
poem = yield get_poetry(host, port)
except Exception, e:
print >>sys.stderr, 'The poem download failed:', e
raise
try:
poem = yield proxy.xform('cummingsify', poem)
except Exception:
print >>sys.stderr, 'Cummingsify failed!'
defer.returnValue(poem)
def got_poem(poem):
print poem
def poem_done(_):
results.append(_)
if len(results) == len(addresses):
reactor.stop()
for address in addresses:
host, port = address
d = get_transformed_poem(host, port)
d.addCallbacks(got_poem)
d.addBoth(poem_done)
reactor.run()
get_transformed_poem inlineCallbacks
( ). ,
( yield) deferred .
6.0, , . , try/except
.
.
:
145
17.4
Deferred, inlineCallbacks
callback'. deferred',
inlineCallbacks . callback'
. , traceback callback', , inline-callbacks/inline-callbacks-tb.py. , traceback, reactor.run(),
callback' .
29,
callback deferred' deferred, , , inlineCallbacks deferred (
yield). 36.
146
. 36: inlineCallbacks
:
.
inlineCallbacks deferred' , ? inlineCallbacks:
callback' , .
callback' , .
callback'
.
try/except.
147
Callback' , . deferred',
,
callback' .
callback'.
, . inlineCallbacks -
.
, callback' , inlineCallbacks.
17.5
inlineCallbacks , callback'
Python .
.
17.6
1. inlineCallbacks ?
2. inlineCallbacks
_inlineCallbacks. .
3. callback' N yield, ,
(if )?
4. 7.0 ,
. , ? , inlineCallbacks,
, ?
5. callback got_poem 7.0 .
148
6. callback poem_done . ! , ,
reactor .
7. yield while . inlineCallbacks?
149
18
18.1
Deferred'
callback' . , deferred', .
. Twisted ,
, , -. , ,
, .
, , ,
? , ( 7.0)
. , ,
, , ,
.
, Twisted ,
,
.
18.2
DeferredList
DeferredList
Deferred deferred. , ,
( ).
.
deferred-list/deferred-list-1.py :
150
Empty List.
Adding Callback.
We got: []
:
DeeredList Python .
, , Deered.
DeferredList - deferred',
Deferred. , callback' errback'
, , deferred.
, callback
, DeferredList
. .
deferred - ().
deferred-list/deferred-list-2.py:
One Deferred.
Adding Callback.
Firing d1.
We got: [(True, 'd1 result')]
:
DeferredList callback,
deferred .
- , .
151
- , - deferred' .
deferred' ( deferred-list/deferredlist-3.py):
Two Deferreds.
Adding Callback.
Firing d1.
Firing d2.
We got: [(True, 'd1 result'), (True, 'd2 result')]
DeferredList, , , -
deferred' , . deferred', deferred', . , DeferredList
deferred' . DeferredList,
, ,
deferred', .
? deferred-list/deferred-list-4.py:
d.addCallback(got_results)
print 'Firing d2.'
d2.callback('d2 result')
print 'Firing d1.'
d1.callback('d1 result')
d2, d1. ,
deferred' d1 d2
. :
Two Deferreds.
Adding Callback.
Firing d2.
Firing d1.
We got: [(True, 'd1 result'), (True, 'd2 result')]
,
deferred', deferred'. ,
,
(, ).
, deferred' ? True?
deferred-list/deferred-list-5.py:
Firing d1.
Firing d2 with errback.
We got: [(True, 'd1 result'), (False, <twisted.python.failure.Failure <type 'exceptions.Exception'>>)]
d2 Failure
False - .
, DeferredList:
153
DeferredList Deferred.
DeferredList deferred, ,
deferred'.
DeferredList deferred' .
deferred'
, . deferred , - (True, result), - (False, failure).
DeferredList , deferred' .
consumeErrors
DeferredList. deferred-list/deferred-list-6.py, , :
Firing d1.
Firing d2 with errback.
We got: [(True, 'd1 result'), (False, >twisted.python.failure.Failure >type 'exceptions.Exception'<<)]
Unhandled error in Deferred:
Traceback (most recent call last):
Failure: exceptions.Exception: d2 failure
, Unhandled error in Deferred , deferred ,
callback deferred' . ,
. ? , DeferredList, DeferredList .
, d2.
DeferredList , deferred',
, . DeferredList - callback errback deferred'. , callback ( errback) (
) . Failure errback errback, d2
.
consumeErrors=True DeferredList, errback,
DeferredList deferred', None, .
, errback d2,
deferred-list/deferred-list-7.py.
154
18.3
8.0
8.0 DeferredList , ( ).
twisted-client-8/get-poetry.py.
poetry_main. :
...
ds = []
for (host, port) in addresses:
d = get_transformed_poem(host, port)
d.addCallbacks(got_poem)
ds.append(d)
dlist = defer.DeferredList(ds, consumeErrors=True)
dlist.addCallback(lambda res : reactor.stop())
8.0 callback poem_done . , deferred,
get_transformed_poem (ds) DeferredList. DeferredList , DeferredList
callback, reactor. , DeferredList, , .
18.4
37 , DeferredList:
. DeferredList,
, , . .
Deferred,
Twisted 10.1.0.
18.5
1. DeferredList.
2. deferred-list reOnOneCallback reOnOneErrback. , ( ).
155
. 37: DeferredList'
3. DeferredList, DeferredList'?
, ?
4. 8.0 ,
, . DeferredList.
5. DeferredDict .
156
19
19.1
deferred'
157
. 38:
Twisted ,
Deferred, . deferred'
, , .
Twisted 10.1.0, : , .
39.
. 39: deferred',
19.2
deferred'
,
deferred'. -
158
, Twisted 10.1.0
. deferred-cancel/defer-cancel-1.py:
done
Unhandled error in Deferred:
Traceback (most recent call last):
Failure: twisted.internet.defer.CancelledError:
deferred'
errback, callback . , twisted.internet.defer.CancelledError,
Exception, , deferred .
errback deferred-cancel/defer-cancel-2.py:
159
160
19.3
Deferred'
deferred-cancel/defer-cancel-5.py:
161
162
. deferredcancel/defer-cancel-9.py:
Sending poem
I got a poem: Once upon a midnight dreary
10 . deferred , .
deferred' 2 :
163
def get_poem():
"""Return a poem 5 seconds later."""
def canceler(d):
# They don't want the poem anymore, so cancel the delayed call
delayed_call.cancel()
# At this point we have three choices:
# 1. Do nothing, and the deferred will fire the errback
#
chain with CancelledError.
# 2. Fire the errback chain with a different error.
# 3. Fire the callback chain with an alternative result.
d = Deferred(canceler)
from twisted.internet import reactor
delayed_call = reactor.callLater(5, send_poem, d)
return d
,
callLater, cancel callback'.
, callback - delayed_call.cancel().
, deferred'.
:
164
, deferred (,
send_poem).
19.4
3.0
, -
,
, , (, , ).
3.0 twisted-server-4/poetry-proxy.py
deferred'. PoetryProxyProtocol:
class PoetryProxyProtocol(Protocol):
def connectionMade(self):
self.deferred = self.factory.service.get_poem()
self.deferred.addCallback(self.transport.write)
self.deferred.addBoth(lambda r: self.transport.loseConnection())
def connectionLost(self, reason):
if self.deferred is not None:
deferred, self.deferred = self.deferred, None
deferred.cancel() # cancel the deferred if it hasn't fired
. :
1. deferred, get_poem ,
, .
2. deferred . , deferred'
, , , , ,
deferred' .
, deferred' .
ProxyService:
class ProxyService(object):
poem = None # the cached poem
def __init__(self, host, port):
self.host = host
self.port = port
def get_poem(self):
if self.poem is not None:
print 'Using cached poem.'
165
166
( Twisted 10.1.0
):
curl localhost:10000
Ctrl-C ,
curl . , ,
:
19.5
, deferred' . .
13 , callback' errback',
deferred', deferred. , () deferred callback deferred'.
, deferred
, ,
, callback deferred'. ,
deferred? deferred ( ); , deferred
deferred.
deferred, , , .
.
deferred-cancel/defer-cancel-12.py:
167
19.6
deferred' ,
, . , , .
168
, , - ,
deferred' . ,
, deferred' , c Twisted Twisted
10.1.0, API Twisted.
, deferred
.
- deferred
API .
,
Twisted, .
-
.
19.7
Deferred, Twisted.
Twisted ,
web . ,
, -,
Twisted. ,
Twisted.
19.8
1. , cancel l?
. .
2. Deferred, .
3. Twisted 10.10 deferred' cancel
callback'. .
4. deferred, get_poetry , .
5. , ,
deferred', deferred'. callLater,
169
, , deferred .
6. API Twisted,
.
Twisted. unit !
170
20
20.1
: Twisted Erlang
, ,
Python Twisted - ,
Twisted ,
, .
,
,
.
Twisted, Python . Twisted,
, ,
Twisted , ,
, .
Twisted. Python' . ,
. Twisted,
( -,
) . ,
,
, Twisted.
Python',
, . Twisted
.
Erlang
- -
(runtime system),
,
. ,
Erlang. , , Erlang, Twisted.
- , , Twisted,
.
http://erlang.org/
171
20.2
(callback)
6. callback 3.0, 6, -
dataReceived. callback ,
, .
, . (
),
,
. .
. 40:
, , -
dataReceived PoetryProtocol.
dataReceived
, ,
( ).
Protocol. "" ,
:
dataReceived(self,
dataReceived(self,
dataReceived(self,
dataReceived(self,
...
172
Python', :
. 41:
for
while.
.
Protocol', , . ,
42.
() ( ). , ,
.
20.3
Erlang
Erlang
1
Python' -
http://erlang.org/
173
. 42: ,
http://ru.wikipedia.org/wiki/Prolog
174
. 43: Erlang
, Twisted, ,
Erlang .
, 44 Erlang .
. 44: Erlang
, Erlang -
select-, Erlang
. Erlang Erlang ,
-
175
. Erlang
-, -, -.
, Erlang ,
,
. . ,
Erlang, .
Twisted , Erlang
Erlang
.
20.4
Erlang
, Erlang'.
, Twisted. ,
Erlang.
.
erlang-client-1/get-poetry. , , , Erlang.
main, , main
, Python':
main([]) ->
usage();
main(Args) ->
Addresses = parse_args(Args),
Main = self(),
[erlang:spawn_monitor(fun () -> get_poetry(TaskNum, Addr, Main) end)
|| {TaskNum, Addr} <- enumerate(Addresses)],
collect_poems(length(Addresses), []).
Prolog , Erlang' .
Python'. main , . Erlang , ,
, ,
(usage). - ,
.
Erlang ,
.
176
.
( Erlang ).
self
Erlang' , -
Erlang ( ).
main, __main__ Python'. :
get_poetry ),
, . ,
( , ).
main
collect_poems,
get_poetry.
,
main, Erlang, , Twisted
.
Erlang
( ), :
get_poetry/4,
get_poetry/3
get_poetry/3, main :
get_poetry
Twisted . , TCP
get_poetry/4, :
PoetryProtocol
Twisted -
, , .
gen_tcp:recv
( ),
. "" Erlang , , Erlang.
TCP
( ,
Erlang). Erlang -
Erlang TCP , select-.
Erlang .
, , Erlang
. , , Erlang
. , Erlang (non-cooperative concurrency model).
,
get_poetry/4
. ,
Erlang ( , ) . Erlang Twisted . Twisted ,
(dataReceived) . Erlang
get_poetry/4 )
.
, ,
get_poetry
main.
get_poetry, .
Erlang collect_poems:
receive
{'DOWN', _, _, _, _} ->
collect_poems(N-1, Poems);
{poem, Poem} ->
collect_poems(N, [Poem|Poems])
end.
get_poetry,
. . receive
main ,
, , (mailbox).
collect_poems
: -
DOWN. DOWN - , -
get_poetry spawn_monitor ). -
main,
(
"DOWN", , .
-
get_poetry
, -
.
, Erlang . :
PATH ).
Windows
escript c Erlang
( Erlang ).
179
. 45: Erlang
. ,
, .
45
get_poetry
) main . , main .
, ? :
get_poetry
180
, Erlang
.
Erlang , ,
. main,
get_poetry , DOWN-
, . , ,
.
20.5
Twisted Erlang :
1. ( )
.
2. , , .
3. ,
.
4. ""( Python , Erlang
) .
5. , , .
, main
. Twisted Deferred, Erlang
(inter-process messages).
, . : , deferred',
callback' ; . , , .
reactor Erlang
. Erlang , :
181
1. - ( , , ).
2. .
Erlang
, (
).
Erlang, . Erlang
gen_server
- ,
, callback, , Erlang .
, Twisted, Erlang
, , .
20.6
Twisted
Erlang, .
Erlang - . Erlang
, (supervisors)
(workers) . , - ( - ).
Erlang',
Erlang', :
Erlang Programming . .
http://www.amazon.com/exec/obidos/ASIN/193435600X/krondonet-20
http://www.amazon.com/exec/obidos/ASIN/0596518188/krondonet-20
3 http://www.amazon.com/exec/obidos/ASIN/1933988789/krondonet-20
1
2
182
Erlang'.
Haskell, , Python' Erlang'. , -
.
20.7
1. Erlang Python ,
, . (, )?
2. Erlang ,
(
).
3. Erlang , ,
.
4. Erlang ,
, .
5. Erlang ,
, .
6. Erlang , Twisted.
183
21
21.1
Twisted Haskell
Twisted Erlang', , .
, -
-
Erlang.
Haskell ,
, Erlang' (, , Python'). , ,
, -.
21.2
Erlang ,
. Haskell
- ,
, . : . ( Erlang'), Haskell
. - , - .
.
, , , (), . ,
, , .
Haskell',
[1,2,3]
http://haskell.org/
http://en.wikipedia.org/wiki/Category_theory
3 http://en.wikipedia.org/wiki/Functor
4 http://en.wikipedia.org/wiki/Monad_%28category_theory%29
5 http://en.wikipedia.org/wiki/Lazy_evaluation
2
184
(Haskell Python
):
head,
head [1,2,3]
GHC Haskell, :
[~] ghci
GHCi, version 6.12.1: http://www.haskell.org/ghc/
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> head [1,2,3]
1
Prelude>
: ? for help
, , - 1.
Haskell . , [2,4 ..]
- , 2. ?
. Haskell [2,4 ..]
() .
185
tail, Haskell , , . ,
() .
Haskell,
:
Prelude>
Prelude>
Prelude>
Prelude>
(3,6,9)
let x = [1..]
let y = [2,4 ..]
let z = [3,6 ..]
head (tail (tail (zip3 x y z)))
, .
, Haskell
, , . Haskell'
46:
. 46: Haskell,
Haskell ,
(, ,
, GHC Haskell). ,
, ,
.
- .
: " ,
". : " ,
". ,
, -.
,
-.
,
,
.
186
Haskell,
Erlang, -
. ,
Haskell.
21.3
Haskell
getPoetry
187
cd haskell-client-1/
ghc --make get-poetry.hs
get-poetry. , :
Task
Task
Task
Task
Task
Task
Task
Task
Task
...
3:
3:
3:
2:
3:
2:
3:
1:
1:
got
got
got
got
got
got
got
got
got
, . . , , , .
, , , ,
.
, ,
. haskell-client2/get-poetry.hs. ,
,
.
, :
cd haskell-client-2/
ghc --make get-poetry.hs
:
, .
,
. ,
, , ,
.
, .
. , ,
, , ,
.
Haskell.
21.4
- , .
1
2
http://www.amazon.com/exec/obidos/ASIN/0596514980/krondonet-20
http://learnyouahaskell.com/
189
Twisted.
21.5
190
22
22.1
, ,
.
Twisted.
22.2
-, .
Twisted web ,
Twisted Book .
, , - Twisted. , Twisted, Twisted.
22.3
1. - Twisted.
2. Twisted .
3. Twisted
patch Twisted.
, .
22.4
http://twistedmatrix.com/trac/wiki/Documentation
http://jcalderone.livejournal.com/50562.html
3 http://www.amazon.com/gp/product/0596100329?ie=UTF8&tag=jpcalsjou20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596100329
4 http://twistedmatrix.com/trac/report
5 http://twistedmatrix.com/trac/wiki/ContributingToTwistedLabs
1
2
191
. 47:
192