Cache library index and refresh changed manga

This commit is contained in:
Codex committed 2026-10-08 21:53:08 +02:00
1 parent eef4ffa07c
commit 8ac27e1f3d
6 files changed
+269 -30

No files matched your search

+16 -6
View File
@@ -4,11 +4,12 @@ MangaCircus does not copy or convert anything. "Import" means **indexing the lib
```
┌───────────── triggers ─────────────┐
│ start-up · every SCAN_INTERVAL min │
│ start-up · shallow interval · daily full │
│ admin "Rescan" · admin "Full rescan"│
└────────────────┬───────────────────┘
▼
library/ ──read──▶ scanLibrary(root, oldCache) library.js
data/library-index.json ──▶ immediate in-memory index at start (if valid)
library/ ──read──▶ shallow changed-manga check or full scan library.js
├─ scanManga (per manga folder)
│ ├─ book folders → parseKey, book.json, cover
│ └─ chapter folders → scanVersion
@@ -20,19 +21,23 @@ MangaCircus does not copy or convert anything. "Import" means **indexing the lib
▼
lib = index (atomic swap, requests see old or new, never half)
▼
data/scan-cache.json (written atomically)
data/scan-cache.json + data/library-index.json (atomic)
```
## 1. Triggers
| Trigger | When | Cache |
|---------|------|-------|
| Start-up | Right after the HTTP server starts listening. Requests are served meanwhile; the library page shows "Scanning…" until the first scan is done | used |
| Interval | Every `SCAN_INTERVAL` minutes (default 10, `0` = off) | used |
| Start-up | Restore the saved index immediately if its library mount is present, then check changed manga. Without a valid snapshot, scan the whole library; the page shows "Scanning…" until done | used |
| Interval | Shallow change check every `SCAN_INTERVAL` minutes (default 10, `0` = off); full reconciliation every `FULL_SCAN_INTERVAL` minutes (default 1440, `0` = off) | used |
| **Rescan** (Settings → Admin, or `POST /api/admin/rescan {}`) | On demand; the request returns when the scan is done | used |
| **Full rescan** (`POST /api/admin/rescan {"full":true}`) | On demand | ignored: every image header is read again |
Scans are **single-flight**. A trigger that fires while a scan is running joins that scan instead of starting a second one.
Scans are **single-flight**. A trigger during a scan queues one coalesced follow-up,
with a full reconciliation taking precedence over a shallow check. Publication
revisions trigger a shallow check; if no changed directory is visible, the reader
falls back to a full scan. In-place edits to `chapter.json` are found by the full
reconciliation or an admin Rescan, not by shallow parent-directory stamps.
## 2. Walking the tree
@@ -155,6 +160,11 @@ The reader lays pages out before they load, so it needs every image's size. Inst
## 4. The scan cache
- Stored in `DATA/scan-cache.json`. It is rewritten atomically after every successful scan and holds only the folders seen in that scan, so deleted chapters drop out.
- `DATA/library-index.json` also stores the complete rebuildable index and shallow
manga/book directory stamps. It lets a restarted reader serve the dashboard and
manga pages before the background filesystem check completes. Both files can be
deleted safely; without the index the next startup walks the library, and without
the size cache it also rereads image headers.
- Invalidation is **per chapter folder, by its mtime**. Adding, removing or renaming a file changes the folder mtime, so that folder is re-read on the next scan.
- **Blind spot:** overwriting an image *in place* (same name) usually doesn't change the folder's mtime, so the old size stays cached. Run a **Full rescan** after such edits, or write new files and rename them (§7).
- Deleting the cache file is harmless. The next scan is simply slower.