~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/examples/longex2.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Example of doing arbitarily long calculations nicely in Twisted.
 
2
 
 
3
This is also a simple demonstration of twisted.protocols.basic.LineReceiver.
 
4
This example uses generators to do the calculation. It also tries to be
 
5
a good example in division of responsibilities:
 
6
- The protocol handles the wire layer, reading in lists of numbers
 
7
  and writing out the result.
 
8
- The factory decides on policy, and has relatively little knowledge
 
9
  of the details of the protocol. Other protocols can use the same
 
10
  factory class by intantiating and setting .protocol
 
11
- The factory does little job itself: it is mostly a policy maker.
 
12
  The 'smarts' are in free-standing functions which are written
 
13
  for flexibility.
 
14
 
 
15
The goal is for minimal dependencies:
 
16
- You can use runIterator to run any iterator inside the Twisted
 
17
  main loop.
 
18
- You can use multiply whenever you need some way of multiplying
 
19
  numbers such that the multiplications will happen asynchronously,
 
20
  but it is your responsibility to schedule the multiplications.
 
21
- You can use the protocol with other factories to implement other
 
22
  functions that apply to arbitrary lists of longs.
 
23
- You can use the factory with other protocols for support of legacy
 
24
  protocols. In fact, the factory does not even have to be used as
 
25
  a protocol factory. Here are easy ways to support the operation
 
26
  over XML-RPC and PB.
 
27
 
 
28
class Multiply(xmlrpc.XMLRPC):
 
29
    def __init__(self): self.factory = Multiplication()
 
30
    def xmlrpc_multiply(self, *numbers):
 
31
        return self.factory.calc(map(long, numbers))
 
32
 
 
33
class Multiply(pb.Referencable):
 
34
    def __init__(self): self.factory = Multiplication()
 
35
    def remote_multiply(self, *numbers):
 
36
        return self.factory.calc(map(long, numbers))
 
37
 
 
38
Note:
 
39
Multiplying zero numbers is a perfectly sensible operation, and the
 
40
result is 1. In that, this example departs from doc/examples/longex.py,
 
41
which errors out when trying to do this.
 
42
"""
 
43
from __future__ import generators
 
44
from twisted.protocols import basic
 
45
from twisted.internet import defer, protocol
 
46
 
 
47
def runIterator(reactor, iterator):
 
48
    try:
 
49
        iterator.next()
 
50
    except StopIteration:
 
51
        pass
 
52
    else:
 
53
        reactor.callLater(0, runIterator, reactor, iterator)
 
54
 
 
55
def multiply(numbers):
 
56
    d = defer.Deferred()
 
57
    def _():
 
58
        acc = 1
 
59
        while numbers:
 
60
            acc *= numbers.pop()
 
61
            yield None
 
62
        d.callback(acc)
 
63
    return d, _()
 
64
 
 
65
class Numbers(basic.LineReceiver):
 
66
    """Protocol for reading lists of numbers and manipulating them.
 
67
 
 
68
    It receives a list of numbers (seperated by whitespace) on a line, and
 
69
    writes back the answer.  The exact algorithm to use depends on the
 
70
    factory. It should return an str-able Deferred.
 
71
    """
 
72
    def lineReceived(self, line):
 
73
        try:
 
74
            numbers = map(long, line.split())
 
75
        except ValueError:
 
76
            self.sendLine('Error.')
 
77
            return
 
78
        deferred = self.factory.calc(numbers)
 
79
        deferred.addCallback(str)
 
80
        deferred.addCallback(self.sendLine)
 
81
 
 
82
class Multiplication(protocol.ServerFactory):
 
83
    """Factory for multiplying numbers.
 
84
 
 
85
    It provides a function which calculates the multiplication
 
86
    of a list of numbers. The function destroys its input.
 
87
    Note that instances of this factory can use other formats
 
88
    for transmitting the number lists, as long as they set
 
89
    correct protoocl values.
 
90
    """
 
91
    protocol = Numbers
 
92
    def calc(self, numbers):
 
93
        deferred, iterator = multiply(numbers)
 
94
        from twisted.internet import reactor
 
95
        runIterator(reactor, iterator)
 
96
        return deferred
 
97
 
 
98
if __name__ == '__main__':
 
99
    from twisted.internet import reactor
 
100
    reactor.listenTCP(1234, Multiplication())
 
101
    reactor.run()