File: longex.py

package info (click to toggle)
twisted 25.5.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 20,560 kB
  • sloc: python: 203,171; makefile: 200; sh: 92; javascript: 36; xml: 31
file content (69 lines) | stat: -rw-r--r-- 2,153 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""Simple example of doing arbitrarily long calculations nicely in Twisted.

This is also a simple demonstration of twisted.protocols.basic.LineReceiver.
"""

from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols import basic


class LongMultiplicationProtocol(basic.LineReceiver):
    """A protocol for doing long multiplications.

    It receives a list of numbers (separated by whitespace) on a line, and
    writes back the answer.  The answer is calculated in chunks, so no one
    calculation should block for long enough to matter.
    """

    def connectionMade(self):
        self.workQueue = []

    def lineReceived(self, line):
        try:
            numbers = [int(num) for num in line.split()]
        except ValueError:
            self.sendLine(b"Error.")
            return

        if len(numbers) <= 1:
            self.sendLine(b"Error.")
            return

        self.workQueue.append(numbers)
        reactor.callLater(0, self.calcChunk)

    def calcChunk(self):
        # Make sure there's some work left; when multiple lines are received
        # while processing is going on, multiple calls to reactor.callLater()
        # can happen between calls to calcChunk().
        if self.workQueue:
            # Get the first bit of work off the queue
            work = self.workQueue[0]

            # Do a chunk of work: [a, b, c, ...] -> [a*b, c, ...]
            work[:2] = [work[0] * work[1]]

            # If this piece of work now has only one element, send it.
            if len(work) == 1:
                self.sendLine(str(work[0]).encode("ascii"))
                del self.workQueue[0]

            # Schedule this function to do more work, if there's still work
            # to be done.
            if self.workQueue:
                reactor.callLater(0, self.calcChunk)


class LongMultiplicationFactory(ServerFactory):
    protocol = LongMultiplicationProtocol


if __name__ == "__main__":
    import sys

    from twisted.python import log

    log.startLogging(sys.stdout)
    reactor.listenTCP(1234, LongMultiplicationFactory())
    reactor.run()