Imported Upstream version 12.1.0
[contrib/python-twisted.git] / doc / core / examples / longex.py
1 """Simple example of doing arbitarily long calculations nicely in Twisted.
2
3 This is also a simple demonstration of twisted.protocols.basic.LineReceiver.
4 """
5
6 from twisted.protocols import basic
7 from twisted.internet import reactor
8 from twisted.internet.protocol import ServerFactory
9
10 class LongMultiplicationProtocol(basic.LineReceiver):
11     """A protocol for doing long multiplications.
12
13     It receives a list of numbers (seperated by whitespace) on a line, and
14     writes back the answer.  The answer is calculated in chunks, so no one
15     calculation should block for long enough to matter.
16     """
17     def connectionMade(self):
18         self.workQueue = []
19         
20     def lineReceived(self, line):
21         try:
22             numbers = map(long, line.split())
23         except ValueError:
24             self.sendLine('Error.')
25             return
26
27         if len(numbers) <= 1:
28             self.sendLine('Error.')
29             return
30
31         self.workQueue.append(numbers)
32         reactor.callLater(0, self.calcChunk)
33
34     def calcChunk(self):
35         # Make sure there's some work left; when multiple lines are received
36         # while processing is going on, multiple calls to reactor.callLater()
37         # can happen between calls to calcChunk().
38         if self.workQueue:
39             # Get the first bit of work off the queue
40             work = self.workQueue[0]
41     
42             # Do a chunk of work: [a, b, c, ...] -> [a*b, c, ...]
43             work[:2] = [work[0] * work[1]]
44     
45             # If this piece of work now has only one element, send it.
46             if len(work) == 1:
47                 self.sendLine(str(work[0]))
48                 del self.workQueue[0]
49             
50             # Schedule this function to do more work, if there's still work
51             # to be done.
52             if self.workQueue:
53                 reactor.callLater(0, self.calcChunk)
54
55
56 class LongMultiplicationFactory(ServerFactory):
57     protocol = LongMultiplicationProtocol
58
59
60 if __name__ == '__main__':
61     from twisted.python import log
62     import sys
63     log.startLogging(sys.stdout)
64     reactor.listenTCP(1234, LongMultiplicationFactory())
65     reactor.run()
66