[Twisted-Python] how to stop dataReceived while waiting a deferred to fire?

Andrea Arcangeli andrea at cpushare.com
Sun Feb 20 23:50:16 EST 2005


My code is like this:

	def stringReceived(string):
		d = somesqlquery(string).addCallback(somecallback)

Now before I can accept more data from the next stringReceived, I have
to validate the "string" with the "somecallback". I don't want to read
more data from the kernel _socket_ until I've the result of
somecallback.

The example in the docs is like this:

-------------------------
class FingerProtocol(basic.LineReceiver):
    def lineReceived(self, user):
        self.factory.getUser(user
        ).addErrback(lambda _: "Internal error in server"
        ).addCallback(lambda m:
            (self.transport.write(m+"\r\n"),
             self.transport.loseConnection()))
[..]
we would have to fetch result from a remote Oracle? Or from the web?
-------------------------

But as far as I can tell the above also is broken and it won't wait for
the deferred to fire, so two of those queries could be invoked if the
client side is malicious and it sends two lines in one packet and that
could screwup the server. It'll work only as long as the clients aren't
malicious.

I really can't see how the reactor could ever wait for the deferred
returned by GetUser and how could lineReceived being throttled in the
above example. So I think the above example needs fixing too.

I need one of those below two solutions:

1) something like protocol.transport.removeReader() to call before
returning from stringReceived (this can be allowed to be different for
stringReceived and dataReceived, since stringReceived will have to stop
the already read data too, and in turn for stringReceived it could be a
protocol.removeReader() that will call protocol.transport.removeReader
internally)

2) I could return a deferred from stringReceived and have the reactor
deregister the fd corresponding to the transport that returned a
deferred until the deferred fires, this is a less finegrined solution
but it's quite handy to code with and it would match the Nevow style of
waiting deferreds

I could try to workaround in my app by stacking some local buffering
with removeReader in the reactor, but it's probably simpler to fix
twisted for it instead.

There must be a way to throttle the input at the kernel level, the recv
syscall must not be called while the deferred is outstanding.

Please help thanks, I'm stuck on this right now...




More information about the Twisted-Python mailing list