python / cpython

The Python programming language
https://www.python.org
Other
63.36k stars 30.34k forks source link

Control flow inconsistency on closed asyncio stream #80021

Open a922e35f-f5a9-46c6-9fb6-3b34ddad725e opened 5 years ago

a922e35f-f5a9-46c6-9fb6-3b34ddad725e commented 5 years ago
BPO 35840
Nosy @pfmoore, @tjguk, @asvetlov, @schlamar, @zware, @1st1, @zooba, @eamanu
Files
  • tcp_test.py
  • tcp_test.py
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['type-bug', '3.7', 'OS-windows', 'expert-asyncio'] title = 'Control flow inconsistency on closed asyncio stream' updated_at = user = 'https://github.com/schlamar' ``` bugs.python.org fields: ```python activity = actor = 'eamanu' assignee = 'none' closed = False closed_date = None closer = None components = ['Windows', 'asyncio'] creation = creator = 'schlamar' dependencies = [] files = ['48082', '48160'] hgrepos = [] issue_num = 35840 keywords = [] message_count = 5.0 messages = ['334450', '334453', '336144', '336252', '336548'] nosy_count = 8.0 nosy_names = ['paul.moore', 'tim.golden', 'asvetlov', 'schlamar', 'zach.ware', 'yselivanov', 'steve.dower', 'eamanu'] pr_nums = [] priority = 'normal' resolution = None stage = None status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue35840' versions = ['Python 3.7'] ```

    a922e35f-f5a9-46c6-9fb6-3b34ddad725e commented 5 years ago

    After closing a StreamWriter the StreamReaderProtocol.connection_lost on the other end is not getting called. In this case the StreamReader is at EOF but calling write/drain does not raise any Exception (and sending data to Nirvana).

    I would expect that StreamWriter.is_closing returns True after the close and calling write/drain raises immediately and not just after the second call. Please see attached example. I see the same behavior with Proactor and Selector event loop on Windows.

    Maybe this is expected behavior. But in this case it is completely undocumented. Should there be a check for StreamReader.at_eof (and maybe StreamReader.exception) before writing to the StreamWriter?

    This might be related to bpo-34176.

    a922e35f-f5a9-46c6-9fb6-3b34ddad725e commented 5 years ago

    After having a closer look I fear that there isn't a correct implementation for half closed sockets and returning True from eof_received results in a fundamentally broken state machine.

    I'm not sure if a selector implementation can handle half closed sockets, at least I'm pretty sure that this is not supported on Windows (https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-select).

    1220ddd9-1292-49f3-b2d8-3f0384085267 commented 5 years ago

    I think that this issue is just for Windows right?

    I add Windows to required a Windows' dev.

    a922e35f-f5a9-46c6-9fb6-3b34ddad725e commented 5 years ago

    No, I'm seeing the same issue on MacOS. Attached modified example.

    1220ddd9-1292-49f3-b2d8-3f0384085267 commented 5 years ago

    Ok, I am working on that.

    willingc commented 4 months ago

    Next action: @python/python-triage, If anyone would like to take a look at this issue and determine the current behavior across operating systems and document the results here, that would be appreciated.