Skip to content

Daemon: async providers, scoped caches, refresh dedup, cancellation #18

Description

@axisrow

Part of #14 (delivery step 3). Depends on the request-scoped extraction; parallel with the lifecycle issue.

Что сделать

  • Async providers in shared mode: Git (git.ts), usage/Keychain (usage-fetch.ts), custom-command (custom-command.ts) via async child_process — sync child-process APIs block the event loop and would let one slow command stall every session.
  • Custom-command capture: adapt custom-command-capture.ts to an asynchronous result in the daemon, retaining output limits, timeouts, EPIPE handling and descendant/process-group cleanup. Do not call the sync Node-spawning helper unchanged inside the server.
  • Git review cache: route the detached refresh path through the same async scheduler instead of re-entering the Node executable. Audit remaining providers for self-spawns and caller-global state (one-process invariant). Legacy sync path stays for one-shot mode.
  • Prefetch: gather data for configured widgets into RenderContext before synchronous widget formatting consumes it (existing registry/formatter/parser reused).
  • Scoped caches (epic table): key by absolute config path + revision / auth profile + credential generation / worktree + cwd / canonical transcript identity. In-flight refresh dedup per key; account/profile separation before any memory-cache fast return; TTL zero still executes per eligible request; missing credentials never select another profile's cached usage.
  • Transcript reuse: validated whole-analysis reuse via file identity/size/mtime/replacement; invalidation tests for truncation, replacement, compaction, partial trailing records, subagent updates. No unconditional full rescan of unchanged files. Incremental tail parsing stays out (conditional follow-up).
  • Concurrency: bounded queues; at most one active + one newest pending render per exact display context; superseded requests resolved explicitly; provider work cancelled when it has no remaining consumers without killing shared refreshes; a slow command or usage fetch never blocks cached responses of other sessions.
  • Bounded memory: cap caches, active jobs and idle retention; never retain full envs, tokens or transcript contents in diagnostics.

Файлы

src/utils/git.ts, src/utils/git-review-cache.ts, src/utils/custom-command.ts, src/utils/custom-command-capture.ts, src/utils/usage-fetch.ts, src/utils/jsonl-metrics.ts, src/daemon/, src/types/RenderContext.ts.

Эталон

PR #9 (jsonl test discipline for truncation/compaction edge cases), PR #2 (provider cost discipline).

Acceptance (from epic)

Simultaneous different configs/accounts/worktrees/widths cannot exchange data; account switch/logout invalidates relevant caches; one slow/hung command does not stall other sessions; memory stays bounded and is reclaimed after idle.

Оценка

  • LOC: ~700–1000 (src ~550 / tests ~350)
  • Размер: XL
  • Время (код): ~100–180 мин
  • Время (review): ~90–120 мин (база 45–60 ×2: concurrency + subprocess management)
  • Время (итого): ~190–300 мин

Priority: medium.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions