Skip to content

fix(websockets): count an abnormal-closure close as unacknowledged - #301

Open
kurok wants to merge 1 commit into
mainfrom
fix/ws-close-abnormal-unacked
Open

kurok wants to merge 1 commit into
mainfrom
fix/ws-close-abnormal-unacked

Conversation

@kurok

@kurok kurok commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Fixes the flaky test_teardown_time_is_not_counted_as_load failure seen on macOS / Python 3.10 in #300 (AssertionError: 0 not greater than or equal to 1 on close_unacked). The flaky test was exposing a real bug in how closes are counted.

Root cause

aiohttp's ClientWebSocketResponse.close() (3.14.5) catches any exception it hits while waiting for the peer's CLOSE frame. It then sets close_code = WSCloseCode.ABNORMAL_CLOSURE (1006) and returns normally. _close_socket only counted close_unacked when close() raised, so a close the server never answered was counted as acknowledged and 1006 was added to close_codes.

RFC 6455 §7.4.1 says 1006 is never sent in a close frame. So it always means no close frame came back, and counting it as unacknowledged is the correct reading.

Change

  • _close_socket: after close() returns, a 1006 close code counts toward close_unacked and is not added to close_codes.
  • New TestCloseSocket unit tests use a fake socket, so they don't depend on reproducing the race. The 1006 test fails on main and passes with this fix.

Testing

  • Full suite: 1942 passed
  • ruff format, ruff check and mypy are clean
  • The slow-close test passed 5 times in a row on Python 3.10

aiohttp's ClientWebSocketResponse.close() swallows a transport error while
waiting for the peer's close frame, stamps ABNORMAL_CLOSURE (1006) and returns
normally. _close_socket took that as an acknowledged close, so close_unacked
under-counted and 1006 leaked into close_codes. 1006 is never sent on the wire
(RFC 6455 7.4.1), so treat it as the unanswered close it is.

This is what made test_teardown_time_is_not_counted_as_load flaky on
macOS/3.10 (close_unacked == 0).

Signed-off-by: kurok <22548029+kurok@users.noreply.github.com>
@codecov

codecov Bot commented Oct 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
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.

1 participant