1
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2
# See LICENSE for details.
5
# Author: Clark Evans (cce@clarkevans.com)
9
flow -- asynchronous data flows using generators
11
This module provides a mechanism for using async data flows through the use of
12
generators. The basic idea of flow is that when ever you require data from a
13
producer, you yield the producer. If the producer is ready, then you can call
14
producer.next() to fetch the incoming data. Otherwise, the underlying
15
controller will suspend the operation to try again later.
17
For example, here is a simple 'printer' which consumes items from its source by
18
printing them. Note that to get a new item, it first yields the data source
19
and then calls source.next()::
21
from __future__ import generators
22
from twisted.flow import flow
23
from twisted.internet import reactor, defer
26
source = flow.wrap(source)
31
someFlowSource = [\"one\", flow.Cooperate(1), \"two\"]
33
d = flow.Deferred(printer(someFlowSource))
34
d.addCallback(lambda _: reactor.stop())
37
In the example above, there are three objects imported from the flow module::
39
- flow.wrap converts many data sources such as lists, generators, and
40
deferreds, into a special instruction object, a Stage. In this case, a
41
simple list is wrapped.
43
- flow.Deferred is a flow Controller which executes the stage passed to it,
44
aggregating all results into a list which is passed to the deferred's
45
callback. In this case, the result list is empty, but the callback is
46
used to stop the reactor after the printing has finished.
48
- flow.Cooperate is a special instruction object which is used by the flow
49
Controller. In this case, the the flow pauses for one second between \"one\"
53
Most classes in the flow module an Instruction, either a CallLater or a Stage.
54
A Stage instruction is used to wrap various sorts of producers, anything from a
55
simple string to Callback functions. Some stages can be constructed directly,
56
such as Zip, Concurrent, Merge, Callback, or Threaded. But in most cases, in
57
particular _String, _List, _Iterable, and _Deferred, state construction is
58
handled through the wrap function. Stages can yield other stages to build a
59
processing chain, results which are returned to the previous stage, or a
60
CallLater instruction which causes the whole operation to be suspended.
63
Typically, the CallLater instructions as passed up the call stack till the top
64
level, or Controller. The controller then typically returns control, but
65
registers itself to be called later. Once called again, the controller sets up
66
the call stack and resumes the top level generator. There is a special
67
CallLater, Cooperate, which simply resumes the chain of stages at a later time.
68
Some stages, Callback, _Deferred, and Threaded have their own special CallLater
69
which handles the process of resuming flow for their specific case.
71
The inheritence hierarchy defined here looks like this::
77
# private stages (use flow.wrap)
97
from twisted.flow.base import *
98
from twisted.flow.stage import *
99
from twisted.flow.pipe import *
100
from twisted.flow.wrap import wrap
101
from twisted.flow.controller import Deferred, Block
102
from twisted.flow.protocol import makeProtocol, Protocol