← Back to PRs

#10801: fix: eagerly initialize QMD memory backend on gateway startup

by 1kuna open 2026-02-07 01:04 View on GitHub →
gateway stale
## Problem QMD memory backend is lazily initialized (only when `memory_search`/`memory_get` is first called). After gateway restarts (config reloads, deploys), the `QmdMemoryManager` instance and its periodic update/embed timer are lost. If no memory tool is used after restart, embeddings go stale silently. ## Solution Add eager initialization of the memory backend on gateway startup. When `memory.backend === 'qmd'`, create the `QmdMemoryManager` and start its periodic timer immediately on boot. ## Changes - **New file** `src/gateway/server-startup-memory.ts`: `startMemoryBackend()` function that: - Resolves configured memory backend from config - If QMD is configured, calls `getMemorySearchManager()` for the default agent - Wraps in try/catch so QMD failures don't block gateway startup - Logs initialization status - **Updated** `src/gateway/server.impl.ts`: Call `startMemoryBackend()` after sidecars start (preserves existing lazy init for tool calls) - **Tests** `src/gateway/server-startup-memory.test.ts`: Verify memory backend initialization logic ## Impact - QMD embeddings stay fresh after every gateway restart - No impact on existing lazy init behavior for memory tools - QMD init failures logged but don't prevent gateway startup Fixes #10797 <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> - Adds a gateway boot hook (`startGatewayMemoryBackendOnBoot`) to eagerly initialize QMD memory when configured, so periodic update/embed timers are armed after restarts. - Updates `getMemorySearchManager` to dedupe concurrent QMD initialization via an in-flight promise cache, and improves QMD boot-update behavior to not block interval retries. - Extends memory backend resolver with a clarifying note and adds targeted Vitest coverage for boot init behavior, QMD init deduping, and timer arming on boot-update failure. <h3>Confidence Score: 3/5</h3> - This PR is directionally correct but has lifecycle/dedup edge cases that could cause incorrect logging or duplicate background work. - Core change (eager QMD init on boot) matches intent and tests cover key paths, but the fire-and-forget boot init isn’t tied into restart/close lifecycle and the new `backend` field is optional, which can misclassify successful QMD init as fallback. There’s also a small robustness issue around clearing the in-flight cache on synchronous construction failures. - src/gateway/server.impl.ts, src/gateway/server-startup-memory.ts, src/memory/search-manager.ts <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs