[Twisted-Python] Re: writing back to the connection is blocking my code
Thomas Hervé
therve at free.fr
Sun Mar 23 06:29:11 MDT 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