commit c56cc3f70588dee30f0bdc267dd3ab5551ac21a0
parent 0eb8ffc8cbbdc2f3a5c7e2268c8dd81c82b2c4c1
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Wed, 30 Sep 2026 09:21:41 -0400
common: review M1 — inFlightPerLocation is at most 8, half the editor's 16 file-access threads, so one drive that stops answering cannot hold every one; the hint, SETTINGS.md and the tests
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/SETTINGS.md b/SETTINGS.md
@@ -556,7 +556,7 @@ Per entry — each entry spells its own values.
| `passIntervalMs` | `15000` | How often the health pass reads each location's disk counters, in ms (default 15000, 5000–300000). A stall that starts between two passes is seen by the next, or at once by a page's read. A save on /storage re-arms the pass's timer at once; a hand edit, at the next pass. Two counter samples are compared only when at least min(10 s, this − 5 s) apart, a spacing never less than half of this. |
| `probeTimeoutMs` | `3000` | How long the health pass waits, in ms (default 3000, 500–30000), for the child `stat` of a root where no disk can be named (a timeout counts as not answering) and for the `findmnt` that names a root's disk (a timeout names none that pass). Takes effect on the next pass. |
| `clearAfterCleanPasses` | `2` | How many clean answers in a row clear a location marked not answering (default 2, 1–10). Each health pass is one answer, and so is a Refresh on /storage; a miss in between starts the count again. Takes effect on the next answer. |
-| `inFlightPerLocation` | `4` | How many reads through the watchdog may be on one location's drive at once (default 4, 1–16); the rest wait in the editor's own queue, so a stall mid-walk holds this many of Node's threads, not all of them. Keep it under `UV_THREADPOOL_SIZE` (16 in the editor's start script). Takes effect on the next read. |
+| `inFlightPerLocation` | `4` | How many reads through the watchdog may be on one location's drive at once (default 4, 1–8); the rest wait in the editor's own queue, so a stall mid-walk holds this many of Node's threads, not all of them. At most 8, half of `UV_THREADPOOL_SIZE` (16 in the editor's start script and the container), so one drive that stops answering cannot hold every thread. Takes effect on the next read. |
Default:
diff --git a/common/lib/storageHealthTimings.test.ts b/common/lib/storageHealthTimings.test.ts
@@ -102,7 +102,7 @@ test("a settings.json round trip: a tuned value is written, read back, and a def
process.env.SETTINGS_FILE!,
JSON.stringify({ storage: { locations: [], health: { inFlightPerLocation: 99 } } }),
);
- assert.deepEqual(getSettings().storage.health, { inFlightPerLocation: 16 });
+ assert.deepEqual(getSettings().storage.health, { inFlightPerLocation: 8 });
});
test("the timings survive the mediaRoot migration (a block with no locations)", () => {
diff --git a/common/lib/storageHealthTimings.ts b/common/lib/storageHealthTimings.ts
@@ -52,7 +52,11 @@ export const HEALTH_TIMING_BOUNDS: Readonly<
passIntervalMs: { min: 5_000, max: 300_000 },
probeTimeoutMs: { min: 500, max: 30_000 },
clearAfterCleanPasses: { min: 1, max: 10 },
- inFlightPerLocation: { min: 1, max: 16 },
+ // At most HALF the editor's 16 file-access threads (`UV_THREADPOOL_SIZE` in
+ // `start` and the container): one drive that stops answering holds this
+ // many of them, and at 16 it would hold every one — the outage the cap
+ // exists to bound.
+ inFlightPerLocation: { min: 1, max: 8 },
});
// In the order the form shows them.
@@ -126,7 +130,7 @@ export const HEALTH_TIMING_HINTS: Readonly<Record<HealthTimingKey, string>> = Ob
clearAfterCleanPasses:
"How many clean checks in a row it takes before a drive marked not answering is used again.",
inFlightPerLocation:
- "How many reads may be on one drive at once; the rest wait their turn, and are refused if it stops answering. Keep it well under the editor's 16 file-access threads: a drive that stops answering holds this many of them.",
+ "How many reads may be on one drive at once; the rest wait their turn, and are refused if it stops answering. At most 8, half the editor's 16 file-access threads: a drive that stops answering holds this many of them.",
});
// SETTINGS.md's `storage.health` table.
@@ -154,8 +158,9 @@ export const STORAGE_HEALTH_SETTINGS_FIELD_DOCS: FieldDocs<StorageHealthSettings
"health pass is one answer, and so is a Refresh on /storage; a miss in between starts the count " +
"again. Takes effect on the next answer.",
inFlightPerLocation:
- "How many reads through the watchdog may be on one location's drive at once (default 4, 1–16); the " +
+ "How many reads through the watchdog may be on one location's drive at once (default 4, 1–8); the " +
"rest wait in the editor's own queue, so a stall mid-walk holds this many of Node's threads, not " +
- "all of them. Keep it under `UV_THREADPOOL_SIZE` (16 in the editor's start script). Takes effect on " +
- "the next read.",
+ "all of them. At most 8, half of `UV_THREADPOOL_SIZE` (16 in the editor's start script and the " +
+ "container), so one drive that stops answering cannot hold every thread. Takes effect on the next " +
+ "read.",
};
diff --git a/editor/app/storage/lib/healthTimingsForm.test.ts b/editor/app/storage/lib/healthTimingsForm.test.ts
@@ -49,7 +49,7 @@ test("a value in range is kept, trimmed; one equal to its default is not written
passIntervalMs: String(HEALTH_TIMING_DEFAULTS.passIntervalMs),
probeTimeoutMs: "500",
clearAfterCleanPasses: "3",
- inFlightPerLocation: "16",
+ inFlightPerLocation: "8",
}),
),
{
@@ -58,7 +58,7 @@ test("a value in range is kept, trimmed; one equal to its default is not written
budgetMs: 4_000,
probeTimeoutMs: 500,
clearAfterCleanPasses: 3,
- inFlightPerLocation: 16,
+ inFlightPerLocation: 8,
},
},
);
@@ -69,9 +69,9 @@ test("out of range is refused with the field, the range and the value — not cl
ok: false,
error: "Read budget must be between 500 and 60000 ms (got 200 ms).",
});
- assert.deepEqual(parseHealthTimingsForm(form({ inFlightPerLocation: "17" })), {
+ assert.deepEqual(parseHealthTimingsForm(form({ inFlightPerLocation: "9" })), {
ok: false,
- error: "Reads at once per drive must be between 1 and 16 (got 17).",
+ error: "Reads at once per drive must be between 1 and 8 (got 9).",
});
assert.deepEqual(parseHealthTimingsForm(form({ clearAfterCleanPasses: "0" })), {
ok: false,