Python twisted - Timeout on a sent message that did not receive a response

I am creating a kind of client-server implementation, and I would like to make sure that every message sent receives a response. Therefore, I want to create a timeout mechanism that does not check whether the message itself has been delivered, but rather checks whether the received message receives a response.

IE, for two computers 1 and 2:

1: send successfully: "hello"
2: <<nothing>>
...
1: Didn't get a response for my "hello" --> timeout

I thought about doing this by creating a large logical array with an identifier for each message that will contain the "in progress" flag, and will be set when the response from the response is received.

I was wondering, maybe there was a better way to do this.

Thanks, Ido.

+3
source share
1 answer

, , , . TimeoutMixin - DeferredLock, , .

from twisted.internet import defer
from twisted.protocols.policies import TimeoutMixin
from twisted.protocols.basic import LineOnlyReceiver

class PingPongProtocol(LineOnlyReceiver, TimeoutMixin):

    def __init__(self):
        self.lock = defer.DeferredLock()
        self.deferred = None

    def sendMessage(self, msg):
        result = self.lock.run(self._doSend, msg)
        return result

    def _doSend(self, msg):
        assert self.deferred is None, "Already waiting for reply!"

        self.deferred = defer.Deferred()
        self.deferred.addBoth(self._cleanup)
        self.setTimeout(self.DEFAULT_TIMEOUT)
        self.sendLine(msg)
        return self.deferred

    def _cleanup(self, res):
        self.deferred = None
        return res

    def lineReceived(self, line):
        if self.deferred:
            self.setTimeout(None)
            self.deferred.callback(line)
        # If not, we've timed out or this is a spurious line

    def timeoutConnection(self):
        self.deferred.errback(
            Timeout("Some informative message"))

, . , :

  • LineOnlyReceiver - , sendLine/lineReceived API .

  • , connectionLost .. , .

  • . , _doSend _cleanup. - _doSend, , . self.deferred, lineReceived ( dataReceived) , .

, , , connectTCP .. TCP-, , .

# Create the protocol somehow. Maybe this actually happens in a factory,
# in which case, the factory could have wrapper methods for this.
protocol = PingPongProtocol()
def = protocol.sendMessage("Hi there!")
def.addCallbacks(gotHiResponse, noHiResponse)
+5

Source: https://habr.com/ru/post/1795172/


All Articles