@parcha/pi-durable-disk 0.1.0-beta.19 → 0.1.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.0-beta.20 (2026-10-20)
6
+
7
+ - A start mark keeper whose rewrite fails because the run's directory moved after its check now warns that the directory is no longer the one it started on, and stops. Before, the `PDA_START_MARK` warning said the rewrite failed (ENOENT or ENOTDIR). Nothing is written in either case; only the stated reason changes.
8
+ - The local-disk env conformance cases watch with a 100 ms poll, so pi's fixed 3 s wait for a report keeps seconds of slack on a loaded runner; the product's 1 s watch default is unchanged.
9
+
5
10
  ## 0.1.0-beta.19 (2026-10-20)
6
11
 
7
12
  - An instance whose app released the run ends by itself: `pi-durable-disk run --app` exits 0 once `onOpen` has returned and the run is released, so the unit does not stay up with no mount.
package/dist/status.js CHANGED
@@ -184,8 +184,9 @@ export function parseStartMark(text) {
184
184
  // watchdog's is (src/watchdog.ts says why). One refresh at a time, all synchronous: a stop (the message) is handled only
185
185
  // between two refreshes, so none is still writing once the thread has exited. It writes only while `dir` is still the
186
186
  // directory it first saw (its device and inode, read on this thread, so a stalled mount never holds the caller's): a path
187
- // that names another (a descriptor number reused) or none is never written, and the keeper stops. Its first failure goes
188
- // to the main thread, once.
187
+ // that names another (a descriptor number reused) or none is never written, and the keeper stops. A rewrite that fails is
188
+ // checked the same way, so a directory that moved between the check and the write is reported as moved, not as a failed
189
+ // write. Its first failure goes to the main thread, once.
189
190
  const KEEPER_SOURCE = `"use strict";
190
191
  const fs = require("node:fs");
191
192
  const path = require("node:path");
@@ -200,19 +201,23 @@ const report = (message) => {
200
201
  reported = true;
201
202
  parentPort.postMessage(message);
202
203
  };
203
- function refresh() {
204
- if (stopped) return;
204
+ // Why dir is no longer the directory the keeper first saw, or null while it is (the first call records it).
205
+ function moved() {
205
206
  let now;
206
207
  try {
207
208
  now = fs.statSync(dir, { bigint: true });
208
209
  } catch (error) {
209
- stopped = true;
210
- return report("its directory cannot be reached (" + (error.code || error.message) + "), so it is no longer the directory the keeper started on");
210
+ return "its directory cannot be reached (" + (error.code || error.message) + "), so it is no longer the directory the keeper started on";
211
211
  }
212
212
  first ??= { dev: now.dev, ino: now.ino };
213
- if (now.dev !== first.dev || now.ino !== first.ino) {
213
+ return now.dev === first.dev && now.ino === first.ino ? null : "its directory is no longer the directory the keeper started on";
214
+ }
215
+ function refresh() {
216
+ if (stopped) return;
217
+ const away = moved();
218
+ if (away) {
214
219
  stopped = true;
215
- return report("its directory is no longer the directory the keeper started on");
220
+ return report(away);
216
221
  }
217
222
  let text;
218
223
  try {
@@ -245,6 +250,12 @@ function refresh() {
245
250
  fs.closeSync(handle);
246
251
  }
247
252
  } catch (error) {
253
+ // The directory may have moved after the check above: then that is the reason, and the keeper stops.
254
+ const away = moved();
255
+ if (away) {
256
+ stopped = true;
257
+ return report(away);
258
+ }
248
259
  report("rewriting it failed (" + (error.code || error.message) + ")");
249
260
  }
250
261
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parcha/pi-durable-disk",
3
- "version": "0.1.0-beta.19",
3
+ "version": "0.1.0-beta.20",
4
4
  "description": "A durable pi host on a network disk (Archil): one owner per run, a fence, durable commits, and a supervisor.",
5
5
  "keywords": [
6
6
  "pi",