tornado iostream multiple callback error : Already reading

618 views
Skip to first unread message

Wesley

unread,
Jan 7, 2014, 4:45:12 AM1/7/14
to python-...@googlegroups.com
Hi all,
   I am using tornado tcpserver, and hit a problem when trying to add read callback.
Scenario is this:
I am the server, and there is one client connecting to me.
1. server sends something to client and read a response(has a read callback here), but , actually, the client hangs, won't send response to server now
2. server sends more thing to client again, and also, wait to read response(with a same callback here), client still hangs.

Snippet of related code:
def writeToDevice(self,data):
        self.to_device = data
        self.timer = Timer(settings.retry_interval,self.feedback_timeout_handle)
        self.timer.start() 
        if self.retry == 0:
            self._stream.write(data,self.wait_feedback)
        else:
            self._stream.write(data)
    
    def write_cb(self):
        self.read_feedback()
        #self.timer.cancel()
    def wait_feedback(self):
        self._stream.read_until_regex('.*\*@\*', self.feed_ok)
    
    def feed_ok(self,data):
        if debug:
            logger.log(10,'Received confirm from %s'%str(self._address))
        self.timer.cancel()

Here comes the problem:
ERROR:tornado.application:Uncaught exception, closing connection.
Traceback (most recent call last):
File "/usrb/python2.6/site-packages/tornado/iostream.py", line 341, in wrapper
callback(*args)
File "/usrb/python2.6/site-packages/tornado/stack_context.py", line 331, in wrapped
raise_exc_info(exc)
File "/usrb/python2.6/site-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "deviceserver.py", line 227, in wait_feedback
self._stream.read_until_regex('.*\*@\*', self.feed_ok)
File "/usrb/python2.6/site-packages/tornado/iostream.py", line 142, in read_until_regex
self._set_read_callback(callback)
File "/usrb/python2.6/site-packages/tornado/iostream.py", line 405, in _set_read_callback
assert not self._read_callback, "Already reading"
AssertionError: Already reading

I see the iostream code here:
def _set_read_callback(self, callback):
        assert not self._read_callback, "Already reading"
        self._read_callback = stack_context.wrap(callback)
So, seems read callback limited to one?
Why?
Apperaciate for any helps.


Thanks.
Wesley

A. Jesse Jiryu Davis

unread,
Jan 7, 2014, 11:10:15 AM1/7/14
to python-...@googlegroups.com
Right, there can be only one read callback. Why? Because if there were two, Tornado wouldn't know which one to call when the stream has readable data.

You should wait until the client responds to the server's message and feed_ok() is executed before calling read_until_regex again. Once that has happened, the IOStream has cleared its read callback and you are allowed to call read_until_regex again.    


--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornad...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Wesley

unread,
Jan 8, 2014, 3:57:48 AM1/8/14
to python-...@googlegroups.com
Why has such limit?
I think we have many such situation.

For example, when first write to client and wait for response, but the client hangs that cannot responses now, and now, we need to send second push to client, so, if we have such limit, the second one will be discarded, or executed only when first one is handled or thrown, why has such limit...



在 2014年1月8日星期三UTC+8上午12时10分15秒,A. Jesse Jiryu Davis写道:

Ben Darnell

unread,
Jan 8, 2014, 2:03:11 PM1/8/14
to Tornado Mailing List
On Wed, Jan 8, 2014 at 3:57 AM, Wesley <nis...@gmail.com> wrote:
Why has such limit?

Because A) no one has asked before and B) adding some kind of queue to allow multiple reads to be pipelined like this would just slow down the common case when you just have one outstanding read at a time.
 
I think we have many such situation.

For example, when first write to client and wait for response, but the client hangs that cannot responses now, and now, we need to send second push to client, so, if we have such limit, the second one will be discarded, or executed only when first one is handled or thrown, why has such limit...

Just schedule the second read after the first one finishes.  TCP delivers data in order so the second read cannot be satisfied before the first in any case.

-Ben
Reply all
Reply to author
Forward
0 new messages