[Twisted-Python] Learning about IPushProducer

Rutt, Benjamin Benjamin.Rutt at gs.com
Fri Mar 16 16:16:51 EDT 2007


Thanks.  One more question.  Any ideas why my server doesn't return any
data at all with the 2nd argument to registration being True?  It just
seems to sit there, but if I flip it to False it works as desired.
(This must be why I set it to False earlier, to get it to run).

I'm using python 2.4 and twisted 2.0.0.

Trivially modified server code, server output and client output are
below, separated by ======================.  Thanks.

#!/usr/bin/env python
import os, os.path, sys, re, commands, pickle, tempfile, getopt,
datetime
import socket, string, random, time, traceback, shutil, popen2

from zope.interface import implements
from twisted.internet import protocol, defer, interfaces, error, reactor
from twisted.internet.protocol import Protocol, Factory
from twisted.protocols.basic import LineReceiver

class NonStarvingXGiver:
    implements(interfaces.IPushProducer)
    def __init__(self, howmany, consumer):
        self.howmany = howmany
        self.sent_already = 0
        self.paused = False
        self.consumer = consumer
        self.act_as_pull = 0
        self.payload1024 = 'x'*1024
    def beginSendingXs(self):
        self.deferred = deferred = defer.Deferred()
        self.consumer.registerProducer(self, True)
        return deferred
    def pauseProducing(self):
        print 'pauseProducing: invoked at %d bytes' %
(self.sent_already)
        self.paused = True
    def resumeProducing(self):
        if not self.act_as_pull:
            print 'resumeProducing: invoked'
        self.paused = False
        maxchunksz = 1024
        while not self.paused and self.howmany > self.sent_already:
            chunksz = min(maxchunksz, self.howmany - self.sent_already)
            if chunksz == 1024:
                self.consumer.write(self.payload1024)
            else:
                self.consumer.write('x' * chunksz)
            self.sent_already += chunksz
            if self.act_as_pull:
                break
        if self.howmany == self.sent_already:
            self.consumer.write('\n')
            self.consumer.unregisterProducer()
            print 'resumeProducing: exiting for the last time'
    def stopProducing(self):
        print 'stopProducing: invoked'
        self.consumer.unregisterProducer()
        
class xgiver(LineReceiver):
    def lineReceived(self, howmany):
        print 'got line [%s] from client [%s]' % (howmany,
 
self.transport.getPeer())
        if howmany == 'bye':
            print 'goodbye to', self.transport.getPeer()
            self.transport.loseConnection()
            return
        try:
            howmany = int(howmany)
            s = NonStarvingXGiver(howmany, self.transport)
            s.beginSendingXs()
        except Exception, ex:
            traceback.print_exc()
            self.transport.write("invalid input " + `howmany` + "\n")

# Next lines are magic:
factory = Factory()
factory.protocol = xgiver

# 8007 is the port you want to run under. Choose something >1024
reactor.listenTCP(8007, factory)
reactor.run()

======================
got line [5] from client [IPv4Address(TCP, '127.0.0.1', 34840)]
got line [4] from client [IPv4Address(TCP, '127.0.0.1', 34840)]
Traceback (most recent call last):
  File "./xgiver.py", line 77, in lineReceived
    s.beginSendingXs()
  File "./xgiver.py", line 39, in beginSendingXs
    self.consumer.registerProducer(self, True)
  File
"/sw/external/python-2.4/lib/python2.4/site-packages/twisted/internet/ab
stract.py", line 266, in registerProducer
    raise RuntimeError("Cannot register producer %s, because producer %s
was never unregistered." % (producer, self.producer))
RuntimeError: Cannot register producer <__main__.NonStarvingXGiver
instance at 0x3a5120>, because producer <__main__.NonStarvingXGiver
instance at 0x3a5198> was never unregistered.
stopProducing: invoked
======================
$ telnet localhost 8007
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
5
4
invalid input 4




More information about the Twisted-Python mailing list