socket programming strategy

Richie Hindle richie at
Wed Jan 22 16:36:40 CET 2003

[Andrew Bennetts]
> An example of doing this in Twisted

> This is a wonderful example

...except for two bugs.  8-)

It falls over when you feed it lots of lines at once (eg. by telnetting
to it and pasting a bunch of lines into the terminal) for two reasons:

 o It deletes completed jobs from the wrong end of the stack.
 o The callback can be called with no work left, so it needs to check
   that the stack isn't empty.

Here's a fixed version, with my edits marked with 'RJH':


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

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

    It receives a list of numbers (seperated 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):
            numbers = map(long, line.split())
        except ValueError:

        if len(numbers) <= 1:

        reactor.callLater(0, self.calcChunk)

    def calcChunk(self):
        # RJH:
        # 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:
                del self.workQueue[0]  # RJH: Not `self.workQueue.pop()`!
            # 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__':
    from twisted.python import log
    import sys
    reactor.listenTCP(1234, LongMultiplicationFactory())


I-know-it's-only-an-example-but-I-can't-help-myself-ly yrs,

Richie Hindle
richie at

More information about the Python-list mailing list