Skip to content

Yield to the event loop during the graph rule loop - #2549

Merged
platypii merged 1 commit into
masterfrom
graph-projection-yield
Oct 8, 2026
Merged

platypii merged 1 commit into
masterfrom
graph-projection-yield

Conversation

@platypii

@platypii platypii commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

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.

@platypii
platypii force-pushed the graph-projection-yield branch from 9f6d6e0 to 50c15cb Compare October 8, 2026 00:22
@platypii

platypii commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

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.

  1. [defer] preference hypaware-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)

@platypii

platypii commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Ship risk: low

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.

@platypii
platypii added this pull request to the merge queue Oct 8, 2026
Merged via the queue into master with commit 5595041 Oct 8, 2026
8 checks passed
@platypii
platypii deleted the graph-projection-yield branch October 8, 2026 00:31
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.

1 participant