finger tutorial: problems rewriting finger08.py to use inlineCallbacks
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. - Paul Goins
On Thu, 11 Dec 2008 11:28:34 +0900 (JST), Paul Goins <general@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
participants (2)
-
Jean-Paul Calderone
-
Paul Goins