python-trio / trio-websocket

WebSocket client and server implementation for Python Trio
MIT License
70 stars 26 forks source link

`get_message()` raises connection closed too early #69

Closed mehaase closed 6 years ago

mehaase commented 6 years ago

While working on documentation, I noticed that WebSocketConnection#get_message() raises ConnectionClosed before checking if there are any items left in the channel–a holdover from the previous Queue-based code.

    async def get_message(self):
        if self._close_reason:                         # BUG
            raise ConnectionClosed(self._close_reason) # BUG
        try:
            message = await self._recv_channel.receive()
        except trio.EndOfChannel:
            raise ConnectionClosed(self._close_reason) from None
        return message

This defeats the purpose of waiting for the end of the channel: a caller should be able to keep calling get_message() to get all queued messages even after a connection is closed.

njsmith commented 6 years ago

The way bsd sockets handle this is: when the remote side closes the connection, you can keep reading everything they sent before until you reach eof. But if the local side closes the connection, then that's it, any pending incoming messages are immediately discarded. Trio channels do the same. So, it might depend on which side set the self._close_reason flag? Or maybe local close should immediately close the receive channel, and get_message should be prepared to get ClosedResourceError from self._recv_channel.receive()?

mehaase commented 6 years ago

Closed via #79.