Skip to content

fix: give reconnect-in-progress submissions a bounded retry window - #225

Open
YishanCoding wants to merge 1 commit into
zarazhangrui:mainfrom
YishanCoding:fix/reconnect-in-progress-retry-window
Open

fix: give reconnect-in-progress submissions a bounded retry window#225
YishanCoding wants to merge 1 commit into
zarazhangrui:mainfrom
YishanCoding:fix/reconnect-in-progress-retry-window

Conversation

@YishanCoding

Copy link
Copy Markdown

Fixes #224

Problem

RunExecutor.submit() rejects immediately with reconnect-in-progress any time activeRuns.newRunsPaused() is true. bot/channel.ts's IM flush handler treats that rejection as terminal — it sends the "当前 bot 正在重连,稍后会继续处理新消息。" notice and discards the message, with no retry. Since reconnect windows are frequently just a few seconds (a WS ping timeout that self-heals — see the keepalive's 15s ping-timeout logic), any message unlucky enough to land in that window is silently lost rather than actually being handled "稍后" as the notice claims.

Fix

  • ActiveRuns gains waitForResume(timeoutMs): Promise<boolean>, resolving true as soon as the current pause is released (all nested pauseNewRuns calls have unwound) or false once timeoutMs elapses first. Implemented with a small waiter list notified from the existing pauseNewRuns release callback — no polling.
  • RunExecutor takes a new optional reconnectWaitMs (default 0). When > 0 and the submission isn't nowait, a paused submit() call waits up to that long for the pause to clear before falling back to the original reconnect-in-progress rejection. nowait submissions are unaffected — they already opt out of waiting for anything (pool included).
  • bot/channel.ts wires reconnectWaitMs: 8000 for the production RunExecutor, matching the keepalive's ping-timeout window.

Compatibility

reconnectWaitMs defaults to 0, which reproduces the exact prior behavior (synchronous, immediate rejection) — every existing test in tests/integration/executor/run-executor.test.ts and tests/unit/runtime/run-executor.test.ts passes unmodified. This is purely additive/opt-in.

Testing

  • New unit tests: tests/unit/bot/active-runs.test.ts (6 cases — resolves immediately when unpaused, resolves on resume before timeout, resolves false on timeout while still paused, non-positive timeout, nested pause/resume only fires once fully unpaused, no waiter leak across cycles).
  • New integration tests in tests/integration/executor/run-executor.test.ts (4 cases — holds and then runs a submission once a short pause clears, still rejects once the wait window elapses, nowait fails fast even with reconnectWaitMs configured, and the default/unset case keeps the immediate-reject behavior).
  • pnpm test:unit, pnpm test:integration, pnpm typecheck, pnpm build all pass. (Pre-existing failures in tests/unit/observability/logger.test.ts and three tests/integration/** files are unrelated — they hardcode the log filename bridge-20260525.jsonl and fail on any other date; confirmed unchanged before/after this change.)

New submissions currently reject immediately with reconnect-in-progress
whenever activeRuns.newRunsPaused() is true, and the caller's message is
dropped rather than retried (see bot/channel.ts's rejectReason handling —
it sends the "正在重连" notice and returns, discarding the batch). Any
in-flight IM message that happens to land during a WS reconnect (a ping
timeout that self-heals in a few seconds is common) is lost and the user
has to notice and resend it by hand.

Add RunExecutor.submit() support for waiting out a short pause before
giving up: ActiveRuns gains waitForResume(timeoutMs), which resolves as
soon as the pause clears or the timeout elapses, whichever comes first.
RunExecutor takes an opt-in reconnectWaitMs (default 0, preserving the
exact current behavior for existing callers/tests) and channel.ts wires
it to 8s in production, matching the keepalive ping-timeout window so a
routine reconnect blip no longer costs the user their message. nowait
submissions are unaffected — they've already asked not to wait.

No behavior change when reconnectWaitMs is left unset.
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.

New IM messages are silently dropped (not retried) during a WS reconnect

1 participant