mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-08-28 05:25:25 +00:00
fix(mcp): detect stale DB after re-indexing and reconnect (#297)
ensureInitialized() now reads meta.json on each tool call to compare indexedAt against the stored loadedAt timestamp. When gitnexus analyze rebuilds the index, the next query closes the stale LadybugDB pool entry and re-opens a fresh connection automatically. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6c18ae08f7
commit
d4d0132b13
4 changed files with 27 additions and 1 deletions
|
|
@ -16,6 +16,7 @@ import { initLbug, executeQuery, executeParameterized, closeLbug, isLbugReady }
|
|||
import {
|
||||
listRegisteredRepos,
|
||||
cleanupOldKuzuFiles,
|
||||
loadMeta,
|
||||
type RegistryEntry,
|
||||
} from '../../storage/repo-manager.js';
|
||||
// AI context generation is CLI-only (gitnexus analyze)
|
||||
|
|
@ -82,6 +83,7 @@ interface RepoHandle {
|
|||
indexedAt: string;
|
||||
lastCommit: string;
|
||||
stats?: RegistryEntry['stats'];
|
||||
loadedAt?: string; // meta.indexedAt when DB was opened — for staleness detection
|
||||
}
|
||||
|
||||
export class LocalBackend {
|
||||
|
|
@ -247,7 +249,24 @@ export class LocalBackend {
|
|||
|
||||
private async ensureInitialized(repoId: string): Promise<void> {
|
||||
// Always check the actual pool — the idle timer may have evicted the connection
|
||||
if (this.initializedRepos.has(repoId) && isLbugReady(repoId)) return;
|
||||
if (this.initializedRepos.has(repoId) && isLbugReady(repoId)) {
|
||||
// Staleness check: did `gitnexus analyze` rebuild the DB since we opened it?
|
||||
const handle = this.repos.get(repoId);
|
||||
if (handle?.loadedAt) {
|
||||
const meta = await loadMeta(handle.storagePath);
|
||||
if (meta?.indexedAt && meta.indexedAt !== handle.loadedAt) {
|
||||
// DB was rebuilt — close stale connection and fall through to re-init
|
||||
await closeLbug(repoId);
|
||||
this.initializedRepos.delete(repoId);
|
||||
this.contextCache.delete(repoId);
|
||||
handle.loadedAt = undefined;
|
||||
} else {
|
||||
return; // Still fresh
|
||||
}
|
||||
} else {
|
||||
return; // No loadedAt tracked yet (first run)
|
||||
}
|
||||
}
|
||||
|
||||
const handle = this.repos.get(repoId);
|
||||
if (!handle) throw new Error(`Unknown repo: ${repoId}`);
|
||||
|
|
@ -255,6 +274,10 @@ export class LocalBackend {
|
|||
try {
|
||||
await initLbug(repoId, handle.lbugPath);
|
||||
this.initializedRepos.add(repoId);
|
||||
|
||||
// Record when we loaded so we can detect staleness later
|
||||
const meta = await loadMeta(handle.storagePath);
|
||||
handle.loadedAt = meta?.indexedAt;
|
||||
} catch (err: any) {
|
||||
// If lock error, mark as not initialized so next call retries
|
||||
this.initializedRepos.delete(repoId);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ const AUGMENT_FTS_INDEXES = [
|
|||
// Mock repo-manager so augment() finds our test DB
|
||||
vi.mock('../../src/storage/repo-manager.js', () => ({
|
||||
listRegisteredRepos: vi.fn(),
|
||||
loadMeta: vi.fn().mockResolvedValue(null),
|
||||
}));
|
||||
|
||||
let augment: (pattern: string, cwd?: string) => Promise<string>;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { LOCAL_BACKEND_SEED_DATA, LOCAL_BACKEND_FTS_INDEXES } from '../fixtures/
|
|||
vi.mock('../../src/storage/repo-manager.js', () => ({
|
||||
listRegisteredRepos: vi.fn().mockResolvedValue([]),
|
||||
cleanupOldKuzuFiles: vi.fn().mockResolvedValue({ found: false, needsReindex: false }),
|
||||
loadMeta: vi.fn().mockResolvedValue(null),
|
||||
}));
|
||||
|
||||
// ─── Block 2: callTool dispatch tests ────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ vi.mock('../../src/mcp/core/lbug-adapter.js', () => ({
|
|||
vi.mock('../../src/storage/repo-manager.js', () => ({
|
||||
listRegisteredRepos: vi.fn().mockResolvedValue([]),
|
||||
cleanupOldKuzuFiles: vi.fn().mockResolvedValue({ found: false, needsReindex: false }),
|
||||
loadMeta: vi.fn().mockResolvedValue(null),
|
||||
}));
|
||||
|
||||
// Also mock the search modules to avoid loading onnxruntime
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue