fix(resolution): stop "Resolving refs" wedge on theme-vendoring repos; add exclude config + index watchdogs (#999) (#1009)
Three fixes for a repo that commits a large JS/TS theme/SDK (Metronic under static/, ~1,600 tracked files): 1. A SECOND "Resolving refs" quadratic that #915 didn't cover. #915 capped import-name collisions; this caps method-name collisions (init/update/render re-declared on every widget), which flow through matchMethodCall Strategy 3 and findBestMatch instead. New AMBIGUOUS_NAME_CEILING (default 500, env CODEGRAPH_AMBIGUOUS_NAME_CEILING): above it the fuzzy strategies decline rather than score K candidates — no proximity score can pick the one true target among thousands anyway. Resolving drops from O(K^2) to linear in refs (e.g. 900-file synthetic: 28.7s -> 3.4s), edge counts unchanged, and the cap never fires on normal repos (max real method-collision ~40). 2. A new `exclude` array in codegraph.json keeps git-TRACKED paths out of the index, which .gitignore can't do (enumeration is `git ls-files`). Mirrors the existing includeIgnored plumbing across the git, sync, and non-git-walk paths. 3. `index`/`init` now install the #850 liveness + #277 ppid watchdogs (which were serve-only), so a wedged or orphaned indexer self-terminates instead of pinning a core. The --liftoff-only relaunch's spawnSync can't forward signals, so killing the parent shim used to orphan the worker. Tests: ubiquitous-name ceiling, exclude (incl. tracked-file exclusion on git + non-git), orphan self-termination (POSIX), and ppid-parser units. Shared the ppid parsers out of mcp/index.ts into mcp/ppid-watchdog.ts. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d3179f5004
commit
45d3293c6a
@@ -10,7 +10,7 @@
|
||||
* stubbing `isAlive` and `platform`.
|
||||
*/
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { supervisionLostReason } from '../src/mcp/ppid-watchdog';
|
||||
import { supervisionLostReason, parsePpidPollMs, parseHostPpid, DEFAULT_PPID_POLL_MS } from '../src/mcp/ppid-watchdog';
|
||||
|
||||
const alive = () => true;
|
||||
const dead = () => false;
|
||||
@@ -136,3 +136,32 @@ describe('supervisionLostReason', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('parsePpidPollMs', () => {
|
||||
it('defaults when unset / empty / non-numeric / negative', () => {
|
||||
expect(parsePpidPollMs(undefined)).toBe(DEFAULT_PPID_POLL_MS);
|
||||
expect(parsePpidPollMs('')).toBe(DEFAULT_PPID_POLL_MS);
|
||||
expect(parsePpidPollMs('abc')).toBe(DEFAULT_PPID_POLL_MS);
|
||||
expect(parsePpidPollMs('-5')).toBe(DEFAULT_PPID_POLL_MS);
|
||||
});
|
||||
it('honours a positive override and floors it', () => {
|
||||
expect(parsePpidPollMs('200')).toBe(200);
|
||||
expect(parsePpidPollMs('150.9')).toBe(150);
|
||||
});
|
||||
it('treats 0 as the explicit "disable" sentinel (caller skips the timer)', () => {
|
||||
expect(parsePpidPollMs('0')).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseHostPpid', () => {
|
||||
it('returns null for unset / empty / non-integer / orphan-sentinel pids', () => {
|
||||
expect(parseHostPpid(undefined)).toBeNull();
|
||||
expect(parseHostPpid('')).toBeNull();
|
||||
expect(parseHostPpid('x')).toBeNull();
|
||||
expect(parseHostPpid('0')).toBeNull(); // unknown
|
||||
expect(parseHostPpid('1')).toBeNull(); // init = already orphaned
|
||||
});
|
||||
it('returns a real positive pid', () => {
|
||||
expect(parseHostPpid('4242')).toBe(4242);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user