[Twisted-web] finger tutorial: problems rewriting finger08.py to use inlineCallbacks

Jean-Paul Calderone exarkun at divmod.com
Wed Dec 10 22:37:01 EST 2008


On Thu, 11 Dec 2008 11:28:34 +0900 (JST), Paul Goins <general at vultaire.net> wrote:
>I'm having problems with using inlineCallbacks in the finger tutorial.
>I've used them successfully in some other test programs, but in this case
>I really don't know what I'm doing wrong.
>
>Here's the FingerProtocol code from the finger tutorial:
>
>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()))
>
>And here's my modified version:
>
>class FingerProtocol(basic.LineReceiver):
>    @defer.inlineCallbacks
>    def lineReceived(self, user):
>        try:
>            data = yield self.factory.getUser(user)
>        except Exception:
>            data = "Internal error in server"
>        self.transport.write(data + "\r\n")
>        self.transport.loseConnection()
>
>For some reason, in my version, the connection is getting terminated
>before any writes can take place.  Even if I comment out the
>loseConnection line, still nothing goes across to the client and the
>connection still gets terminated.
>
>Could anyone tell me where I'm going wrong on this?  Thanks in advance.

By decorating your lineReceived with inlineCallbacks, you made it return
a Deferred.  If lineReceived returns non-None, the protocol disconnects
itself.

One solution would be to put your inlineCallbacks-decorated generator
code into another function, call it from lineReceived, and discard the
return value.

This preserves a minor problem with your current implementation though,
which is that if a client sends you two lines and the Deferred returned
by the second call to getUser fires first, you'll write out the second
user's info and then close the connection.  This isn't a major flaw for
a finger server to have, since a client is only allowed to send you one
line, but it's something to keep in mind if you use inlineCallbacks in
a more complicated application.

Jean-Paul



More information about the Twisted-web mailing list