zettelkasten.synapse.worker¶
zettelkasten.synapse.worker ¶
Long-lived WARM synapse READ worker (search/frame).
Same query dispatch as :mod:zettelkasten.synapse.query, but instead of running
one query and exiting, this worker stays alive and services many requests over a
line-delimited JSON protocol on stdin/stdout. This keeps the expensive state WARM
across queries:
- the process-global
model2vecmodel is loaded once (see :mod:zettelkasten.embeddings); - the ZK grapher caches each box's :class:
~zettelkasten.graph.ZettelGraph(and its kglite embedding index) in a process-global registry, rebuilding it only on first access — and :func:zettelkasten.server._get_graphre-checks on-disk mtimes each call, so external writes are still picked up (bounded staleness);
so only the FIRST query in a worker pays the cold-start + index-build cost;
subsequent queries reuse the warm indexes. Crash isolation is preserved exactly
as for the one-shot :mod:~zettelkasten.synapse.query path: the worker is a
separate process, so a native kglite/model2vec SIGSEGV kills only the worker (the
parent respawns it) and never the stdio MCP server. :mod:faulthandler is
enabled so a crash dumps the Python traceback (which frame drove into native
code) to stderr, which the parent captures.
Protocol — one JSON object per line on stdin, one line per response on stdout::
<- {"action": "search"|"frame", ...} # same payload as the one-shot query CLI
-> SYNAPSE_QUERY_RESULT <json> # exactly one result line per request
The worker prints SYNAPSE_WORKER_READY once at startup so the parent can tell
a spawned worker from a hung one. EOF on stdin => clean exit. All logs and any
fault trace go to stderr; stdout carries only the ready line and result lines.