[Twisted-Python] timeout and retries
Stefano Canepa
sc at linux.it
Fri Jun 17 08:41:17 MDT 2005
The following code is a try to write a protocol with timeout and
retries. The connectioMade is used only as a test. I have some problems:
1) even if I placed "\x01" as delimiter the line is sent not terminated
2) even if timeout expired 3 times the success callback is called
Were is my mistake?
Secondly I will prefer to leave the protocol as simple as passible and
put all implementation details into the factory. I was unable to do
this, any suggestion would be of big help.
Thanks very much
Stefano
#!/usr/bin/env python
#
# Twisted modules
#
from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor, defer
#
# Python modules
#
import re
#
# if it exists load configuration file
#
try:
import HL7LLPClientConfig
except:
#
# else use defaults
#
TIMEOUT = 10
PORT = 3000
SERVER = 'localhost'
RETRIES = 3
pass
class HL7LLPClientProtocol(LineReceiver):
"""
HL7 Lower Level Protocol initiating module implementation.
It sends a packet, waits ACK/NACK or timeout in case of failure
retries RETRIES times
"""
# delimiter is set to <EB> (\x02 i.e. STX) so that the whole HL7
message
# can be considered as a string
delimiter = "\x02"
msg = ""
def __init__(self):
self.ackMSG = re.compile("\x01\x06")
self.nackMSG = re.compile("\x01\x15")
def connectionMade(self):
self.sendMsg("MSH|||||||||||")
def sendMsg(self, msg, numRetries=RETRIES):
"""
Store the message to be used by derived classes, send the
message and
return a deferred
"""
self.msg = msg
self.sendLine(msg)
return self.timeoutAndRetry(numRetries)
def sendLine(self, msg):
"""
Add <SB> (\x01 i.e. SOH) at the start of message as required by
HL7 standard and send the message
"""
msgToSend = "\x01"+msg
print msgToSend
self.transport.write(msgToSend)
print "written"
def lineReceived(self, response):
"""
It receives the answer store it for use in the derived class and
verify if it is ACK or NACK to cancel the timeout, every other
string received is not valid answer so timeout continues to tick
"""
m = self.ackMSG.match(response)
n = self.nackMSG.match(response)
if m or n:
self.delayedCall.cancel()
self.delayedCall = None
self.somethingResult.callback()
self.somethingResult = None
def timeoutAndRetry(self, n):
"""
Create a deferred, fire the delayedCall, and return the deferred
"""
d = defer.Deferred()
d.addErrback(self.tooManyRetries)
d.addCallback(self.success)
c = reactor.callLater(10, self._timeout, n)
self.somethingResult, self.delayedCall = d, c
return d
def _timeout(self, n):
"""
Retry to send if possible or raise and exception
"""
print n
if n > 0:
d = self.somethingResult
#self.sendMsg(self.msg, n - 1).chainDeferred(d)
self.sendMsg(self.msg, n - 1)
else:
self.somethingResult.errback(Exception("TooManyRetries"))
self.somethingResult = None
def timeOutFailure(self, reason):
"""
Don't know what to do in case of timeout
"""
print "timeout failure %s " % reason
def tooManyRetries(self, reason):
"""
Don't know what to do in case of non timeout failure
"""
print "non timeout failure %s" % reason
def success(self, reason):
"""
Don't know what to do in case of success
"""
print "success %s" % reason
class HL7LLPClientFactory(ClientFactory):
protocol = HL7LLPClientProtocol
def main():
factory = HL7LLPClientFactory()
reactor.connectTCP(SERVER, PORT, factory)
reactor.run()
if __name__ == "__main__":
main()
--
Stefano Canepa aka sc: sc at linux.it http://www.stefanocanepa.it
Three great virtues of a programmer: laziness, impatience and hubris.
Le tre grandi virtù di un programmatore: pigrizia, impazienza e arroganza.
(Larry Wall)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: </pipermail/twisted-python/attachments/20050617/33b9b72f/attachment.sig>
More information about the Twisted-Python
mailing list