fix(sync): report stalled syncs as unhealthy - #1419
Conversation
A failed network mount can block a filesystem call while the daemon remains alive. Operators need to distinguish that state from a sync that is still making progress without breaking the ping identity contract used to find and control the existing daemon. Mark active passes as stalled after five minutes without progress and expose that state through ping and sync status. Keep ping identity valid so recovery does not start a second daemon. Reject new foreground syncs promptly when an existing pass owns the engine instead of waiting behind the blocked call.
Watcher push batches enter reconciliation through the shared locked helper. They need to publish progress before discovery for the same reason as scheduled passes: a blocked filesystem traversal must be visible in daemon health no matter which reconciliation entry point reached it.
roborev: Combined Review (
|
Watcher path batches can block before their first parser returns. Publish initial progress before starting workers so daemon health can mark that work stalled instead of remaining healthy.
roborev: Combined Review (
|
Changed-path preparation can block before the engine owns or reports the pass. Post-sync mirror callbacks can outlive completed progress and make healthy work look stalled. Track preparation only after acquiring sync ownership, and end sync progress before mirror callbacks. This keeps daemon health aligned with actual sync work without weakening serialization.
roborev: Combined Review (
|
Worker resyncs and unknown-rename planning can block before daemon health sees any active work. Operators need those owned phases to age into the same stalled state as in-process syncs. Relay resync worker progress through the parent engine and plan production watcher batches only after acquiring sync ownership. Clear both records on every exit so completed work does not remain unhealthy.
roborev: Combined Review (
|
Daily archive audits can block while holding exclusive sync ownership without publishing progress. Daemon health then looks healthy even though all other sync work is blocked. Track the direct worker pass after it acquires ownership and relay child updates. Clear the record on every exit so audit completion does not leave stale health state.
roborev: Combined Review (
|
Daily audit workers can continue reconciling sessions without emitting heartbeats. The parent then ages the initial audit marker into a false stalled state even while work advances. Forward reconciliation discovery and page progress through the worker protocol. This keeps daemon health current for active audits while preserving stalled detection when work stops.
roborev: Combined Review (
|
Windows can return the same clock tick immediately after a progress update. Tests that use a one-nanosecond stall interval can therefore observe active progress before it has aged into the stalled state. Keep the simulated sync work blocked and wait for the real stalled transition. This preserves the health contract assertions without depending on platform clock granularity.
roborev: Combined Review (
|
…dy-core * origin/main: (25 commits) ci: retry failed Docker image builds (kenn-io#1437) Speed up HTTP sync by processing only changed sessions (kenn-io#1414) chore: remove dead code and unused frontend exports (kenn-io#1434) fix(parser): populate Kimi session cwd (kenn-io#1427) feat(frontend): add raw and formatted tool output display (kenn-io#1424) feat(insights): support OpenAI-compatible endpoints (kenn-io#1430) fix(parser): support legacy Zed thread schemas (kenn-io#1429) perf(signals): index duplicate prompt comparisons (kenn-io#1425) fix(config): honor explicit empty agent directory arrays (kenn-io#1423) feat(parser): add DeepSeek Harness session support (kenn-io#1402) test(sync): wait for archive audit stall state (kenn-io#1422) chore(deps): update github actions dependencies (kenn-io#1421) Tombstone stored Claude sessions a complete full parse no longer emits (kenn-io#1392) fix(sync): report stalled syncs as unhealthy (kenn-io#1419) Reduce idle CPU and let users turn off unused providers (kenn-io#1374) fix(serve): survive dual-stack port collisions at startup (kenn-io#1406) fix(sync): bound startup reconciliation and expose daemon identity (kenn-io#1413) fix(deps): update module golang.org/x/mod to v0.40.0 [security] (kenn-io#1400) Persist Claude and Codex freshness digests across engine restarts (kenn-io#1393) fix(sync): add lifecycle logging (kenn-io#1399) ...
Fixes #1403.
A failed network mount can leave the daemon alive while a sync pass is blocked
inside a filesystem call. Ping now preserves
ok: truefor daemon identity butreports
healthy: falsewith stalled sync details after five minutes withoutprogress. Sync status exposes the same timestamps and stalled flag.
In-process and worker-backed passes publish progress through the parent daemon.
Worker resyncs and daily archive audits are visible before their first worker
event and relay subsequent updates. Watcher batches acquire sync ownership
before rename planning, source preparation, discovery, or parsing. Coordinated
syncs clear progress after signal flushing and before PostgreSQL or DuckDB mirror
callbacks, so post-sync work is not mislabeled as stalled. New foreground sync
requests still fail promptly while another pass owns the engine; background work
remains serialized.
This detects the blocked state rather than attempting to cancel an uninterruptible
filesystem call. Operators can recognize and recover an unhealthy daemon without
clients treating the live process as missing and starting a duplicate.