Skip to content

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 model2vec model 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_graph re-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.