[Twisted-Python] Re: writing back to the connection is blocking my code

Thomas Hervé therve at free.fr
Sun Mar 23 08:29:11 EDT 2008


Le Friday 21 March 2008 18:11:58 coder_gus, vous avez écrit :
> Yup, that made it alot clear and thanks so much for it :)
>
> But now another question comes up: what if for a special client I want
> to inject some data ... let's say that while he is processing some
> tasks, the backend observes that some data in the database has altered
> and wants to notify the client that he can't use that data anymore - if
> I am using deferToThread I don't think sending data back trough that is
> pretty easy ... or am I wrong?

Indeed, that's not a problem. You just have to pass something to your task 
that will allow it to send data back, and remember that Twisted is not 
threadsafe so that you must use reactor.callFromThread. Let's get back to our 
example:

def blockingTask(content, safeWrite):
     import sqlalchemy
     # sqlalchemy stuff
     query = session.query("bla")
     data  = query.getresult()
     if data == "unexpected":
         safeWrite("Not expected!")
         # But I continue my task
     ....
     return result


class CommandProtocol(Protocol):
     def __init__(self):
         self.buf = ''

     def safeWrite(self, data):
         reactor.callFromThread(self.transport.write, data)

     def dataReceived(self, data):
         self.buf += data
         # This is stupid, don't do that
         while '</end_command>' in self.buf:
              content, self.buf = self.buf.split('</end_command>', 1)
              content += '</end_command>'
              deferToThread(blockingTask, content,     
                      self.safeWrite).addCallback(self.response)

     def response(self, result):
         # I got the response event!
         self.sendLine.write("response %s" % (result,))


See? We're passing a method to the task, so that you can send notification 
whenever you want. In practice, you'll have to check if the connection is 
still alive, but the main thing to remind is to use reactor.callFromThread.

-- 
Thomas




More information about the Twisted-Python mailing list