
from zope.interface import implements
from twisted.internet import reactor, stdio, task
from twisted.protocols import basic
from twisted.internet.interfaces import IHalfCloseableProtocol

class EchoItemProtocol(basic.LineReceiver):
    implements(IHalfCloseableProtocol)
    delimiter = '\n'
    def __init__(self):
        self.outstanding = []
        self.inputDone = False
    def lineReceived(self, item_id):
        # Item.get returns a deferred
        d = task.deferLater(reactor, 1.0, lambda : item_id)
        self.outstanding.append(d)
        def writeResponse(item):
            self.transport.write(str(item) + '\n')
        d.addCallback(writeResponse)
        def done(result):
            self.outstanding.remove(d)
            self.maybeDone()
            return result
        d.addBoth(done)
    def readConnectionLost(self):
        self.inputDone = True
        self.maybeDone()
    def maybeDone(self):
        if self.inputDone and not self.outstanding:
            self.transport.loseWriteConnection()
    def writeConnectionLost(self):
        reactor.stop()

def main():
    stdio.StandardIO(EchoItemProtocol())
    reactor.run()
if __name__ == '__main__':
    main()
