WebSocket API: in-flight requests are lost on serverShutdown, rotation or a dropped connection (caller gets a 20 s timeout)
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 55/100
Hướng nghiên cứu
Start with common/src/binance_common/websocket.py, especially receive_loop, reconnect(), _discard_connection and send_message; the report also points to common/tests/unit/test_fault_injection.py and test_initiates_renewal_on_server_shutdown. Run the three InFlight fault injection tests to reproduce the lost replies and delayed errors. Done means pending callers receive replies from the old socket when available, and get a prompt connection error when it closes.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
A WebSocket API request that is in flight when its connection is replaced or dropped never gets its answer. The caller waits the full 20 s and receives {"error": "timeout"}, even when the server already executed the request. For order.place this is the worst case for a trading client: the order exists, the client reports a timeout, and a retry places it again.
Three paths lead there, all in common/src/binance_common/websocket.py (master 13fda51, binance-common 4.8.0):
serverShutdown(lines 325-337).receive_loopawaitsschedule_reconnect(..., 5, close_old_connection=False)inline, so the old socket is not read for 5 s plus the time to open the new connection.connection.reconnectstaysFalseon this path, sosend_messagekeeps routing new requests to the old socket during that window.reconnect()(lines 845-846), used both forserverShutdownand for the 23 h rotation. It runsconnection.pending_request.clear()without resolving the futures. A reply that arrives afterwards has an id that is no longer inpending_requestand falls through to the "Received message" branch, so the waiting caller never sees it.- Connection closed (
receive_loopexit and_discard_connection, lines 427-449 and 495-522). The socket is closed and removed from the pool, but the pending futures are not failed. Callers only find out whenasyncio.wait_for(future, timeout=20)expires (the same 20 s is hardcoded at lines 1076, 1344, 1698, 1790 and 1895).
The Binance docs describe serverShutdown as sent "when the server is about to shut down ... Please establish a new connection as soon as possible", so the old connection is still alive when the event arrives and can still answer requests already sent on it.
Reproduction
Tests against a real local aiohttp WebSocket server (no mocks), branch Amadeus-22:hunt/failure-modes:
cd common
python -m pytest -q tests/unit/test_fault_injection.py -k InFlight
FAILED test_request_after_server_shutdown_gets_the_servers_answer - server answered order.place at once, caller got nothing after 3.0s
FAILED test_request_pending_when_connection_drops_fails_promptly - connection closed at once, caller still waiting after 3.0s
FAILED test_request_answered_during_rotation_reaches_the_caller - request in flight at rotation got nothing after 3.0s
With the library's real 20 s wait, all three cases return {'error': 'timeout'} after 20.0 s, while the server log shows order.place received (and answered, in the shutdown and rotation cases).
Proposed fix (small, websocket.py only)
- serverShutdown: start the replacement with
asyncio.create_task(...)instead of awaiting it insidereceive_loop, and mark the connection as draining so new requests go to the new connection while the old loop keeps delivering replies to requests already sent. - reconnect(): do not
clear()pending futures that the old socket can still answer; before the old socket is finally closed, fail whatever is left withConnectionError. - Connection closed: fail every unfinished future with
ConnectionErrorwhenreceive_loopexits.send_messagealready turns exceptions into{"error": ...}, so callers learn immediately instead of after 20 s.
On a scratch copy these three changes make the tests above pass; the only existing test that needs updating is test_initiates_renewal_on_server_shutdown, which asserts the inline await.
Not verified
- Against the live API: how long Binance keeps answering on a connection after sending
serverShutdown. The drop and rotation cases do not depend on it. - The session-logon variant (the extra 1 s re-logon window in
reconnect()).
The hardcoded 20 s request wait also ignores ConfigurationWebSocketAPI.timeout, documented as "Request timeout in milliseconds (default: 5000)"; I left that out of scope.
Happy to open a PR with the fix and these tests if this direction looks right.
- Ngôn ngữ chính
- Python
- Star
- 3k
- Fork
- 712
- Merge trung bình
- 1 ngày 13 giờ
- Pull request đã merge (30 ngày)
- 9
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của binance/binance-connector-python
-
USDⓈ-M exchangeInfo:请明确 POSITION_RISK_CONTROL / positionControlSide 的语义与枚举Có thể đã có người làm @Tyagiquamar đã nhận 2 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 15/100
binance/binance-connector-python#575 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] Response models declare numeric fields as strict `str`, causing silent fallback of `.data()` to raw dict (simple-earn & staking)Có thể đã có người làm @Tyagiquamar đã nhận 48 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 68/100
binance/binance-connector-python#553 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 20/100
binance/binance-connector-python#498 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
binance/binance-connector-python#464 · 1 bình luận · 5 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Type hint mismatch for list API responsesCó thể làm lại được @AyeshaNasirWebDeveloper đã nhận 78 ngày trước và không có pull request nào đang mở. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 58/100
binance/binance-connector-python#444 · 1 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của binance/binance-connector-python
Issue tương tự
-
fuzz fuzz-unconfirmed
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
ready-for-agent
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
neilsh/stunt-reel#220 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Issue]: use_fp4_cache is accepted but ignored; the launcher always writes FP8 recordsCó thể đã có người làm @0z5a đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
area: cli priority: p3 size: S type: bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
finos/open-resource-broker#757 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 6 ngày