[Twisted-Python] Error (and response) handling in protocols
Phil Mayers
p.mayers at imperial.ac.uk
Mon Feb 21 04:18:12 MST 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