Reputation: 2521
I am using twisted to handle a text based protocol. Initially the client connects to server. After connecting, server will send commands to which the client should respond to. Each type of commands takes different amount of time to formulate a response. (eg: an return a value from local hash versus returning a value from a complex MySQL query on a big database). The response from client should go in the order the command was received. Server will not wait for a response from one command before sending another command, but expects response in the order command was sent. Client cannot expect any order for commands sent from server.
Following is a minimal code showing the outline of how my program works currently.
class ExternalListener(LineReceiver):
def connectionMade(self):
log.msg("Listener: New connection")
def lookupMethod(self, command):
return getattr(self, 'do_' + command.lower(), None)
def lineReceived(self, verb):
method = self.lookupMethod(verb)
method(verb)
def do_cmd1(self, verb):
d = self.getResult(verb)
d.addCallback(self._cbValidate1)
def _cbValidate1(self):
resp = "response"
self.transport.write(resp)
def do_cmd2(self, verb):
d = self.getResult(verb)
d.addCallback(self._cbValidate1)
def _cbValidate2(self):
resp = "response"
self.transport.write(resp)
As it can be seen, this will not take care of ordering of responses. I am not in a position to use DeferredList because deferreds are created as and when a command is received and there is no list of deferreds which I can put in a DeferredList.
What is the twisted way to handle this scenario?
Thanks and Regards,
Upvotes: 0
Views: 138
Reputation: 48315
One solution is to use a protocol with tags for requests and responses. This means you can generate responses in any order. See AMP (or even IMAP4) as an example of such a protocol.
However, if the protocol is out of your control and you cannot fix it, then a not-quite-as-nice solution is to buffer the responses to ensure proper ordering.
I don't think there is any particularly Twisted solution here, it's just a matter of holding responses to newer requests until all of the responses to older requests has been sent. That's probably a matter of using a counter internally to assign an ordering to responses and then implementing the logic to either buffer a response if it needs to wait or send it and all appropriate buffered responses if it doesn't.
Upvotes: 1