Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch ClosedResourceError. Fixes #134 #140

Merged
merged 3 commits into from
Sep 22, 2020
Merged

Conversation

nmichaud
Copy link
Contributor

No description provided.

@coveralls
Copy link

coveralls commented Sep 21, 2020

Pull Request Test Coverage Report for Build 106

  • 1 of 1 (100.0%) changed or added relevant line in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.2%) to 95.697%

Totals Coverage Status
Change from base Build 97: 0.2%
Covered Lines: 467
Relevant Lines: 488

💛 - Coveralls

Copy link
Member

@belm0 belm0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to include a test that reproduces the error when fix isn't applied.

@nmichaud
Copy link
Contributor Author

This test is not quite deterministic - it seems to fail every 10 invocations. I'm going to see if i can narrow down the exact sequence of steps.

@nmichaud
Copy link
Contributor Author

nmichaud commented Sep 21, 2020

@belm0 I don't know if you can help me fix the test, the sequencing is a bit tricky - the issue seems to occur because _send_channel is closed while the reader task is still processing an event, so this line https://github.com/HyperionGray/trio-websocket/blob/master/trio_websocket/_impl.py#L1071 throws a trio.ClosedResourceError (trio.BrokenResourceError is only thrown when the _recv_channel is closed).

@nmichaud
Copy link
Contributor Author

@belm0 OK this test consistently fails before the fix.

Comment on lines 735 to 751
async def test_server_sends_after_close(nursery):
async def handler(request):
server_ws = await request.accept()
with pytest.raises(ConnectionClosed):
while True:
await server_ws.send_message('Hello from server')

server = await nursery.start(serve_websocket, handler, HOST, 0, None)
stream = await trio.open_tcp_stream(HOST, server.port)
client_ws = await wrap_client_stream(nursery, stream, HOST, RESOURCE)
async with client_ws:
# pump a few messages
for x in range(2):
await client_ws.send_message('Hello from client')
await stream.aclose()


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

due to the way the nursery fixture works, the nursery will be cancelled if the test function exits

so I'm concerned that there may be non-determinism since nothing ensures that the handler test code is able to complete

Usually in this case, I'd make a done = trio.Event() at the start of the test function, set() it at the end of handler(), and await done.wait() at the end of the test function.

This may explain the non-determinism in the original test, and you may be able to get away with only one send_message() now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realize that about the nursery fixture. I'll update the test.

I tried many iterations before I could reproducibly cause the failure. The trickiness is that it seems to a race condition between the reader_task and the main handler code on the server side, and in particular when there is data that hasn't been processed by the reader task but the underlying stream has already been closed. For example, changing line 740 above to await server_ws.get_message() doesn't trigger the error, and only sending a single message on the client side also doesn't trigger an error.

@belm0
Copy link
Member

belm0 commented Sep 22, 2020

thank you for spending time on a test ❤️

@belm0 belm0 merged commit 50b62cb into python-trio:master Sep 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants