Repository navigation
Description
Current Behavior
Admin serializes WebSocket writes through one SessionSendQueue per session. The queue advances only when the callback passed to AsyncRemote.sendText executes.
If the async send never invokes its callback—for example on a half-open connection, stalled ingress/LB path, or a non-reading client—sending remains true forever. Later configuration messages are appended to an unbounded ArrayDeque, but no call restarts sendNext().
There is no configured async-send timeout, queue limit, oldest-message deadline, or watchdog.
When a callback reports failure, or sendText throws, the current message is logged and discarded. The session is not closed and no gateway full resynchronization is requested. Because WebSocket events have no ACK/replay cursor, the gateway can remain stale until restart.
Reproduction
- Mock
RemoteEndpoint.Async#sendTextso the first send never invokes itsSendHandler. - Send two or more updates to the same session.
- Verify only the first call reaches
sendText; subsequent messages remain queued indefinitely. - In a second case, return a failed
SendResultand verify the failed update is discarded without closing the session or triggeringMYSELF.
Expected Behavior
A blocked or failed WebSocket send must be detected within a bounded time and force a recoverable connection state. Configuration updates must not remain silently queued or be dropped without reconciliation.
Scope
- Configure or implement a bounded per-message send timeout.
- Bound the per-session queue by count and/or bytes.
- On timeout or send failure, stop the queue, remove the session from all indexes, close it, and allow the gateway to reconnect and perform
MYSELFfull synchronization. - Preserve message ordering for healthy sessions.
- Define behavior for queue overflow; silent drop is not acceptable.
- Add metrics for queue length/bytes, oldest message age, in-flight duration, timeout, failure, overflow, and forced reconnect.
- Cover races among callback completion, timeout,
onClose, and new messages.
Acceptance Criteria
- A missing send callback cannot stall a session queue indefinitely.
- Failed sends cannot leave the gateway silently stale.
- Queue memory use is bounded.
- Failure/timeout removes the session and its queue from all maps.
- Reconnect triggers a full synchronization before normal incremental delivery resumes.
- Ordering is preserved on healthy connections.
- Unit tests cover no-callback, failed callback, synchronous exception, overflow, close race, and recovery.
- An integration test reproduces a stalled/broken WebSocket connection and verifies final cache convergence.
Activity
github-actions commentedon Sep 26, 2026
👋 Hello @Aias00
A new issue has been opened by @Aias00:
Please review when you have time. Thank you! 🙏
Fixes apache#7313: Close stalled websocket sessions and bound the adm…