Open benediamond opened 4 years ago
@garenchan sorry to bother—not sure if you have any thoughts on this. thanks.
Also having this problem. Do you know where might a safe (and close-to-the-source) place be to catch this with a try/except block until this is fixed?
Also running into this after upgrading from python 3.7.6 to 3.8.6
Also running into this after upgrading from python 3.7.6 to 3.8.6
Thanks. I solved this problem by downgrading python to 3.6
you can avoid this by using an asyncio.Event()
to wait for the on_close(
method to be called
Here I created an async def aclose(
method, which you can gather when shutting down your server gracefully:
import functools
import asyncio
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import tornado.web
class Handler(tornado.websocket.WebSocketHandler):
def initialize(self, *, handlers):
self._handlers = handlers
self._closed = asyncio.Event()
def open(self):
self._handlers.add(self)
def on_message(self, message):
pass
def on_close(self):
self._handlers.remove(self)
self._closed.set()
def check_origin(self, origin):
return True
async def aclose(self):
self.close()
await self._closed.wait()
return self.close_code, self.close_reason
async def my_function():
handlers = set()
application = tornado.web.Application(
[
(r"/", Handler, {"handlers": handlers}),
]
)
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8080)
try:
await asyncio.sleep(20.0)
finally:
http_server.stop()
await asyncio.gather(*(handler.aclose() for handler in handlers))
asyncio.run(my_function())
The root cause of this issue is that WebSocketHandler.close
is not immediate - it begins the process of shutting down the websocket connection, but this takes a little time (the server sends a close frame to the client, then waits for the client to respond with its own close frame before closing the TCP connection). We don't currently have a clean way to wait for this process to complete - @graingert 's use of the on_close
hook is the best workaround for now. We should incorporate something like that into WebSocketHandler to give you a good way to close all your connections and wait for them to shut down cleanly.
NOTE: this is different from https://github.com/tornadoweb/tornado/issues/2763. possibly related to https://github.com/tornadoweb/tornado/issues/2448, but also distinct.
After starting a websocket server, I am getting
even after appropriately closing all connections. this is different from https://github.com/tornadoweb/tornado/issues/2763, where the unresolved task was
WebSocketProtocol13._receive_frame_loop
, and not all connections were closed.to reproduce this easily, run the following tiny python3 program:
in a separate Node.js console (for example), run:
the culprit appears to be the future
fut
here, which is never awaited: https://github.com/tornadoweb/tornado/blob/79b9c4fcbb3728f1325c4f6120bec45dd5df9fd8/tornado/web.py#L2323-L2326 tornado version:tornado-6.0.4
. Python version:3.8.5
.i am unable to further diagnose the issue, or fix it. thanks for your attention and time.