[Python-modules-team] Bug#949974: More details
Enrico Zini
enrico at enricozini.org
Mon Jan 27 20:46:35 GMT 2020
Hello,
I tracked the issue: in http1connection.py, the write method does:
self._pending_write = self.stream.write(fchunk)
self._pending_write.add_done_callback(self._on_write_complete)
The Future[1] documentation says:
Callbacks registered with add_done_callback() are always called via
the event loop’s call_soon_threadsafe().
So although self._pending_write in that case is already in a 'done'
state, self._on_write_complete is only called the next time we'll
reenter the event loop.
Meanwhile, before returning to the event loop, the flow of the code
continues and RequestHandler.finish calls:
self.request.connection.finish()
It detects correctly that there is still a pending write, and calls:
future_add_done_callback(self._pending_write, self._finish_request)
However, future_add_done_callback does not schedule self._finish_request
for the next ioloop iteration like Future.add_done_callback does:
# concurrent.py:
def future_add_done_callback(future, callback):
# …
if future.done():
callback(future)
else:
future.add_done_callback(callback)
Compare with:
# In concurrent.py, class Future:
def add_done_callback(self, fn):
# …
if self._done:
from tornado.ioloop import IOLoop
IOLoop.current().add_callback(fn, self)
else:
self._callbacks.append(fn)
So self._finish_request is called before self._on_write_complete,
_clear_callbacks() is called, which resets self._write_callbacks.
When control returns to the event loop, _on_write_complete is finally,
called, which finds self._write_future set to None, and won't trigger
the future that will permit RequestHandler.flush() to continue.
If there is still data to write, self._pending_write is not done when
future_add_done_callback is called, and RequestHandler.flush() won't get
stuck.
Enrico
[1] https://www.tornadoweb.org/en/stable/concurrent.html#tornado.concurrent.Future.add_done_callback
--
GPG key: 4096R/634F4BD1E7AD5568 2009-05-08 Enrico Zini <enrico at enricozini.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/python-modules-team/attachments/20200127/c0a5cbe4/attachment-0001.sig>
More information about the Python-modules-team
mailing list