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
{{ message }}
Repository navigation
Yield to the event loop during the graph rule loop - #2549
The projection's rule loop runs over a scan's fully materialized rows with no await, so on the HypAware server each day slice blocked the event loop for seconds (17 s on hyperparam's busiest day), stalling every request meanwhile.
The loop now yields with setImmediate once it has run for 50 ms, checking the clock every 256 rows so the per-row cost is one bitmask test.
Local repro on the server, hyperparam graph projection (cache plus a 7.1 GB archive), identical results:
wall
event loop blocks over 1 s
worst
before
499 s
34
17.4 s
after
487 s
0
under 1 s
CPU and memory: no new allocation per row; one clock read per 256 rows.
Review of master...graph-projection-yield (1 commit, 3c2238c..50c15cb) - clean
The graph projection's rule loop iterates fully materialized scan results with no await, so a large source table blocked the daemon's event loop for seconds. This change checks the clock every 256 rows and yields via setImmediate once 50 ms have passed, at both the shared declarative scan and the raw-SQL rule scans. The node/edge maps are local to the call and the function already awaited between scans, so the new yield points add no new interleaving hazard. The yield helper matches the existing pattern in context-graph/src/query.js. CPU/memory pass: one performance.now() per 256 rows and one microtask hop per 50 ms slice; no new allocation or growth.
[defer] preferencehypaware-core/plugins-workspace/context-graph/src/project.js:144 - no test asserts the loop yields
A test could feed a stub __executeSql with many rows and a slow rule, then assert a setImmediate callback runs before projectGraph resolves. It is timing-sensitive and the change is small and directly readable; safe to land without it.
Reviewers: Claude, Codex (no findings; its npm test run failed only on missing dependencies in the fresh worktree, unrelated to this change)
Who could be affected: People running HypAware's background service while it builds the activity graph.
What could happen: No plausible user-facing failure found. The change only lets the background service pause briefly to answer other requests while it builds the graph, instead of making them wait for seconds. The graph it builds is the same.
Why this level: It changes when work happens, not what is produced, and it does not touch stored data, privacy, or access.
What was checked: A large simulated build produced exactly the same graph before and after the change, and the service stayed responsive throughout (no pause over about 50 milliseconds). The existing graph-building tests all pass.
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
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.
The projection's rule loop runs over a scan's fully materialized rows with no await, so on the HypAware server each day slice blocked the event loop for seconds (17 s on hyperparam's busiest day), stalling every request meanwhile.
The loop now yields with
setImmediateonce it has run for 50 ms, checking the clock every 256 rows so the per-row cost is one bitmask test.Local repro on the server, hyperparam graph projection (cache plus a 7.1 GB archive), identical results:
CPU and memory: no new allocation per row; one clock read per 256 rows.