fix(core): bound consumed job history - #46087
Open
Hona wants to merge 1 commit into
Open
Conversation
Retain at most 100 claimed terminal jobs and 16 MiB of output/error text in completion order. Preserve unclaimed handoffs, running work, pending notification ownership, and full results for registered waiters.
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
Bound the process-global Job registry's consumed terminal history to the newest 100 jobs and 16 MiB of UTF-8 output/error text, evicting whole entries in completion order. Only
packages/core/src/job.tschanges.Completed foreground shell and subagent jobs currently remain in the registry for the server's lifetime. Closing a job's scope does not remove its Info and Deferred-held result snapshots. Notification acknowledgment currently removes only the durable KV marker.
Retention Policy
block()claims a foreground result; registered waiters already hold their generation's Deferred and still receive the full result after eviction.wait()claims non-recoverable output. Recoverablewait()alone does not: the existingwait -> backgroundhandoff remains supported, including immediately failed work.get/wait/blockcalls use their existing missing-result shapes. Oversized results still reach the first caller in full; they are not truncated to fit history.The byte budget covers output and error strings, not arbitrary metadata or total heap size. Metadata is bounded only by the history entry count. Running work, unclaimed handoffs, pending notifications, and caller-held results can exceed these limits; this is not a hard cap on total Job or server memory.
Before / After
One graph, two measured checkpoints per version, with the median of five fresh processes on Windows x64 / Bun 1.4.0. The fixture uses the production Job service and real in-memory SQLite KV. Each job produces a distinct, materialized synthetic 1-MiB result string and has its foreground result claimed through
block(). This is not 1 MiB of normal shell stdout; default shell previews are smaller.The Job service remains alive during measurement. Both versions use the same warm-up and eight explicit full-GC rounds with 100-ms event-loop gaps. All unrelated weak controls are collected, retained metadata sentinels match readable history counts, and retained results remain complete. A separate 1,000-job run with 50-KiB results retains exactly 100 entries, exercising the count limit rather than the text-byte limit.
Metric:
bun:jsc.heapStats().heapSize, including external memory, not RSS or a production-server savings forecast. A preliminary batch run alongside integration tests failed a reachability control; the final plotted batch ran separately and passed all controls. The graph and validation probes are local artifacts, not committed files.Verification
bun typecheck, targeted Oxlint, Effect AST rules, Prettier, andgit diff --checkpassed. The pre-push workspace typecheck passed all 33 tasks.No test files or changesets are included. The running server was not patched or restarted for validation.