Process split: cangcang (daemon) + cangjian (web) #143

Closed
opened 2026-08-12 06:03:59 +00:00 by agent-pi · 1 comment
Collaborator

Cang currently runs as a single process doing ingest, cleanup, and web serving in one asyncio event loop. All DB operations share aiosqlite's single background thread, so during periodic scans web requests queue behind writes and the UI hangs.

Split into two processes — cangcang (ingest/cleanup daemon) and cangjian (web server). Both share SQLite via WAL mode.

Also fixes issue #131 (deploy-docs token handling).

Design spec: .superpowers/specs/2026-08-12-cang-process-split-design.md

Cang currently runs as a single process doing ingest, cleanup, and web serving in one asyncio event loop. All DB operations share aiosqlite's single background thread, so during periodic scans web requests queue behind writes and the UI hangs. Split into two processes — cangcang (ingest/cleanup daemon) and cangjian (web server). Both share SQLite via WAL mode. Also fixes issue #131 (deploy-docs token handling). Design spec: .superpowers/specs/2026-08-12-cang-process-split-design.md
Author
Collaborator

Plan of attack

Two new entry points from the existing codebase, no logic changes:

  1. src/cang/daemon.py — extract all ingest/cleanup/periodic-loop functions from web/lifespan.py into a new module. Exposes run_daemon(cfg, db).
  2. src/cang/web/server.py — new cangjian entry point. Plain FastAPI() app (no lifespan), uvicorn.
  3. web/app.py — drop lifespan import and kwarg.
  4. Delete cli.py and web/lifespan.py.
  5. ContainerfileCMD ["cangjian", "/config/cang.toml"] instead of ENTRYPOINT.
  6. CI — fix stale container annotations + harden deploy-docs token (#131).
  7. Quadlets — pod-level shared volumes, separate cangcang.container and cangjian.container.
  8. Follow-up issue — ability to mark snapshots as keep/do-not-delete.

Full plan: .superpowers/plans/2026-08-12-cang-process-split.md
Design spec: .superpowers/specs/2026-08-12-cang-process-split-design.md

## Plan of attack Two new entry points from the existing codebase, no logic changes: 1. **`src/cang/daemon.py`** — extract all ingest/cleanup/periodic-loop functions from `web/lifespan.py` into a new module. Exposes `run_daemon(cfg, db)`. 2. **`src/cang/web/server.py`** — new `cangjian` entry point. Plain `FastAPI()` app (no lifespan), uvicorn. 3. **`web/app.py`** — drop lifespan import and kwarg. 4. **Delete** `cli.py` and `web/lifespan.py`. 5. **`Containerfile`** — `CMD ["cangjian", "/config/cang.toml"]` instead of ENTRYPOINT. 6. **CI** — fix stale container annotations + harden deploy-docs token (#131). 7. **Quadlets** — pod-level shared volumes, separate `cangcang.container` and `cangjian.container`. 8. **Follow-up issue** — ability to mark snapshots as keep/do-not-delete. Full plan: `.superpowers/plans/2026-08-12-cang-process-split.md` Design spec: `.superpowers/specs/2026-08-12-cang-process-split-design.md`
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marvin8/cang#143
No description provided.