[Twisted-Python] Error (and response) handling in protocols

Phil Mayers p.mayers at imperial.ac.uk
Mon Feb 21 06:18:12 EST 2011


On 21/02/11 10:39, Jason Heeris wrote:
> On 21 February 2011 15:58, Michael Thompson<michaelnt at gmail.com>  wrote:
>> The app should be waiting on the result of a deferred (which it
>> expects to fire with the result of the serial comms) so you can simply
>> errback that deferred.
>
> I get that bit, but my question is essentially: what triggers the
> errback? If the LineReceiver gets a line that's too long, *how* do I
> errback on the deferred? Should the protocol hold the deferred? The
> factory? Whatever creates the factory? Does it matter? ("No" would be
> a fine answer to the last question, my whole problem is that I don't
> really know the "Twisted" way to approach this, or if there even is
> one.)

Normally, all the protocol logic, including sending commands and 
returning responses/errors, lives on the protocol.

For example, if you have a line-based proto it might look like this:

class MyProto(...bases...):

   def connectionMade(self):
     self.queue = []
     self.current = None

   def lineReceived(self, line):
     if self.current is None:
       # eh? we've received a line with no outstanding command
       return
     deferrred = self.current
     self.current = None

     try:
         # do some parsing
         result = parse(line)
     except:
         deferred.errback()
     else:
         deferred.callback(result)

     if self.queue:
         # there's an outstanding command
         deferred, cmd = self.queue.pop(0)
         self.current = deferred
         self.sendLine(cmd)

   def send_cmd(self, cmd)
     deferred = defer.Deferred()
     if self.current is None:
         # no outstanding command, issue this one
         self.current = deferred
         self.sendLine(cmd)
     else:
         # queue it, there's an outstanding command
         self.queue.append((deferred, cmd))
     return deferred


def test():
     d = proto.send_cmd('foo')
     d.addCallback(lambda x: ...)
     d.addErrback(lambda e: ...)


...you can then layer timeout, cancellation and other logic on top of 
this, using various techniques.



More information about the Twisted-Python mailing list