feat(pi-ext): per-request timeout + stall-kill for mempalace-mcp
A wedged mempalace-mcp (classically an OrbStack virtiofs cold-open of a large chroma.sqlite3 / HNSW load) left the awaiting JSON-RPC promise pending forever, freezing the pi TUI uninterruptibly: ESC cancels the LLM stream, not a pending tool execute(). The JSON-RPC client now arms a per-request timer. On expiry it rejects the request AND kills the stalled child (SIGTERM->SIGKILL), so pi gets an error instead of hanging; the extension flips available=false so later calls fail fast (restart pi to retry). Per-REQUEST, not per-process: the long-lived server only dies on a genuine stall. Knobs: MEMPALACE_MCP_TIMEOUT_MS (default 60000), MEMPALACE_MCP_INIT_TIMEOUT_MS (default 120000), 0 = disable. This supersedes the planned standalone stdio-watchdog shim: the extension already owns request/response correlation, so a separate framing-reparsing shim is unnecessary.
This commit is contained in:
@@ -52,6 +52,23 @@ to `"pi"`. First diary write against that identity creates `wing_<name>`
|
||||
in the palace. Set the env var if you want to run pi under a distinct
|
||||
identity on a given machine (e.g. `pi-laptop` vs `pi-server`).
|
||||
|
||||
## Stall protection (per-request timeout)
|
||||
|
||||
Every JSON-RPC request to `mempalace-mcp` carries a timeout. Without it, a
|
||||
wedged server (classically: an OrbStack/virtiofs cold-open of a large
|
||||
`chroma.sqlite3` or an HNSW load) leaves the awaiting promise pending
|
||||
*forever*, which freezes the pi TUI — ESC cancels the LLM stream, not a
|
||||
pending tool `execute()`. On timeout the extension rejects the request
|
||||
**and** kills the stalled child (SIGTERM→SIGKILL), so pi gets a clear
|
||||
error instead of hanging and later calls fail fast (`available` flips off;
|
||||
restart pi to retry). This is a per-REQUEST timeout, not a process-lifetime
|
||||
one — the long-lived server is only killed when a request genuinely stalls.
|
||||
|
||||
- `MEMPALACE_MCP_TIMEOUT_MS` — tool-call/request timeout. Default `60000`.
|
||||
- `MEMPALACE_MCP_INIT_TIMEOUT_MS` — `initialize` + `tools/list` handshake
|
||||
timeout (cold-open is expected to be slower here). Default `120000`.
|
||||
- Set either to `0` to disable (legacy unbounded behavior).
|
||||
|
||||
## Debugging
|
||||
|
||||
- `MEMPALACE_EXT_DEBUG=1` — surface `mempalace-mcp` stderr into pi's
|
||||
|
||||
Reference in New Issue
Block a user