fix(session-fork): add 2s timeout to parent-fork token count resolution#10
Open
hugenshen wants to merge 1 commit into
Open
fix(session-fork): add 2s timeout to parent-fork token count resolution#10hugenshen wants to merge 1 commit into
hugenshen wants to merge 1 commit into
Conversation
Wrap the transcript read + byte-stat path in a withTimeout so a slow or very large parent transcript cannot stall session creation indefinitely. On timeout the caller falls back to cached totalTokens or the byte-size estimate already accumulated before the deadline, whichever is larger. Fixes openclaw#101718
Dependency GuardThis PR changes dependency-related files. Maintainers should confirm these changes are intentional. Changed files:
Maintainer follow-up:
|
Dependency graph changes notedThis PR includes dependency graph changes. The dependency guard is informational because the PR author is a repository admin or a member of
Security review is still recommended before merge when the dependency graph change is intentional. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
resolveParentForkTokenCountRuntimereads the parent transcript file and parses recent usage with no timeout or abort boundary. On a large transcript (hundreds of MB) or a slow filesystem (NFS, FUSE, saturated SSD), the async call can hang indefinitely, blocking every new thread/reply in the session and exhausting async context slots in the gateway.withTimeout(2 000 ms). Before the timeout fires, the function accumulates abestEffortTokensvalue (cachedtotalTokensfrom the store entry, then the byte-size estimate fromfs.stat). If the deadline is exceeded the timeout error is caught and the best-effort value is returned, keeping session creation moving.bestEffortTokensmutation inside thewithTimeoutclosure and whether the catch path correctly returns the last accumulated value.Linked context
Closes openclaw#101718
Real behavior proof (required for external PRs)
pnpm devnot running — unit-test-only proof; no live gateway needed for this path).{ status: "fork", maxTokens: 100_000 }when runtime returnsundefined.vi.useFakeTimers+vi.advanceTimersByTimeAsync.vi.useFakeTimersdrives the timeout, so this is deterministic unit proof rather than real-clock wall-time proof. The production path (withTimeoutfrominfra/fs-safe) uses realsetTimeout; the unit tests confirm the branching logic is correct.Tests and validation
node scripts/run-vitest.mjs src/auto-reply/reply/session-fork.runtime.test.ts --run --reporter=verbose— 8/8 passnode scripts/run-vitest.mjs src/auto-reply/reply/session-fork.test.ts --run --reporter=verbose— 2/2 passsession-fork.runtime.test.ts(timeout with cached fallback; timeout with byte-estimate fallback); one new test insession-fork.test.ts(fork decision when runtime returnsundefined)Risk checklist
bestEffortTokensvariable is mutated inside the async closure beforewithTimeoutresolves; ifestimateParentTranscriptTokensFromBytesthrows synchronously that value staysundefinedand the catch returnsundefined— same as the old behavior.estimateParentTranscriptTokensFromBytesalready has its owntry/catchand returnsundefinedon error; the only new failure mode is the timeout path, which is tested.Current review state
codex reviewnot run (no local Codex binary available in this checkout).