You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three small changes to QwpWebSocketSender that close a silent-loss
window in the async client:
1. close() now captures the first Throwable raised during the
flush/drain path, finishes shutdown of the I/O thread, socket
and microbatch buffers, and then rethrows. Previously a HALT
policy SenderError surfaced from drainOnClose was swallowed
into a LOG.error(), so a user who only ever called close()
(no flush() afterwards) had no way to observe the failure and
no signal that data was lost. A static rethrowTerminal helper
wraps any non-RuntimeException Throwable in a LineSenderException
so close() keeps its existing throws contract.
2. drainOnClose now throws a LineSenderException on timeout
carrying publishedFsn, ackedFsn, and the count of unacked
batches, instead of logging a WARN and returning silently.
The exception propagates through close() via mechanism (1)
above. SF-mode users can recover the unacked tail by reopening
on the same SF directory; memory-mode users have no recovery
path and must treat this as fatal.
3. Adds two accessors so tests and user code can observe
storage-drained progress without polling internal state:
- getAckedFsn() returns the highest server-acknowledged FSN
(or -1 before the I/O loop has started).
- awaitAckedFsn(targetFsn, timeoutMillis) blocks until
acked >= target or the timeout elapses, returning a
boolean and surfacing latched I/O errors via
cursorSendLoop.checkError(). Pair with
flushAndGetSequence() to wait for a specific publish
to land on disk server-side.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments