@rljson/fs-agent 0.0.59 → 0.0.60
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/dist/fs-agent.d.ts +30 -0
- package/dist/fs-agent.js +39 -0
- package/package.json +1 -1
package/dist/fs-agent.d.ts
CHANGED
|
@@ -190,6 +190,16 @@ export declare const RESTORED_BLOB_MEMORY_MAX = 50000;
|
|
|
190
190
|
* high concurrency is how a client runs out of heap.
|
|
191
191
|
*/
|
|
192
192
|
export declare const RESTORE_FETCH_CONCURRENCY = 16;
|
|
193
|
+
/**
|
|
194
|
+
* How many of its own past states a node remembers.
|
|
195
|
+
*
|
|
196
|
+
* Used to recognise a sender that is BEHIND this node — one that declares a
|
|
197
|
+
* state this node has held and left. A burst on a large folder produces a few
|
|
198
|
+
* dozen states, so this is generous; forgetting the oldest costs only the
|
|
199
|
+
* ability to spot a very stale sender, which the mass-delete guard still
|
|
200
|
+
* catches.
|
|
201
|
+
*/
|
|
202
|
+
export declare const STATE_HISTORY_MAX = 1000;
|
|
193
203
|
/**
|
|
194
204
|
* What an agent concluded about an inbound ref.
|
|
195
205
|
*
|
|
@@ -290,6 +300,15 @@ export declare class FsAgent {
|
|
|
290
300
|
/** Files written vs left alone by the current {@link restore}. */
|
|
291
301
|
private _restoreWritten;
|
|
292
302
|
private _restoreSkipped;
|
|
303
|
+
/**
|
|
304
|
+
* The states this node has held, oldest first.
|
|
305
|
+
*
|
|
306
|
+
* A push declaring one of these — but not the current one — comes from a
|
|
307
|
+
* sender that is behind this node. Applying such a tree is what puts a
|
|
308
|
+
* deleted file back, so it is ignored outright rather than applied
|
|
309
|
+
* additively.
|
|
310
|
+
*/
|
|
311
|
+
private readonly _stateHistory;
|
|
293
312
|
/**
|
|
294
313
|
* Absolute paths of the files this agent has actually TOLD anyone about.
|
|
295
314
|
*
|
|
@@ -753,6 +772,17 @@ export declare class FsAgent {
|
|
|
753
772
|
* its own pushes, and the states it adopts from theirs.
|
|
754
773
|
* @param tree - The tree that just went out, or was adopted as ours.
|
|
755
774
|
*/
|
|
775
|
+
/**
|
|
776
|
+
* Records a state this node is now in.
|
|
777
|
+
* @param ref - The content ref of that state.
|
|
778
|
+
*/
|
|
779
|
+
private _rememberState;
|
|
780
|
+
/**
|
|
781
|
+
* Whether a push comes from a sender this node has already moved past.
|
|
782
|
+
* @param predecessorRefs - What the push declares it descends from.
|
|
783
|
+
* @returns True when every declared parent is a state this node has left.
|
|
784
|
+
*/
|
|
785
|
+
private _senderIsBehind;
|
|
756
786
|
private _rememberAnnounced;
|
|
757
787
|
private _adoptAppliedRef;
|
|
758
788
|
/**
|
package/dist/fs-agent.js
CHANGED
|
@@ -1080,6 +1080,7 @@ const REFUSAL_ANSWER_COOLDOWN_MS = 5e3;
|
|
|
1080
1080
|
const TREE_FETCH_CONCURRENCY = 64;
|
|
1081
1081
|
const RESTORED_BLOB_MEMORY_MAX = 5e4;
|
|
1082
1082
|
const RESTORE_FETCH_CONCURRENCY = 16;
|
|
1083
|
+
const STATE_HISTORY_MAX = 1e3;
|
|
1083
1084
|
const VERDICT_REASON = {
|
|
1084
1085
|
"own-echo": "is this agent's own last advertisement echoed back",
|
|
1085
1086
|
stale: "is not the newest its sender has advertised"
|
|
@@ -1153,6 +1154,15 @@ class FsAgent {
|
|
|
1153
1154
|
/** Files written vs left alone by the current {@link restore}. */
|
|
1154
1155
|
_restoreWritten = 0;
|
|
1155
1156
|
_restoreSkipped = 0;
|
|
1157
|
+
/**
|
|
1158
|
+
* The states this node has held, oldest first.
|
|
1159
|
+
*
|
|
1160
|
+
* A push declaring one of these — but not the current one — comes from a
|
|
1161
|
+
* sender that is behind this node. Applying such a tree is what puts a
|
|
1162
|
+
* deleted file back, so it is ignored outright rather than applied
|
|
1163
|
+
* additively.
|
|
1164
|
+
*/
|
|
1165
|
+
_stateHistory = [];
|
|
1156
1166
|
/**
|
|
1157
1167
|
* Absolute paths of the files this agent has actually TOLD anyone about.
|
|
1158
1168
|
*
|
|
@@ -1268,6 +1278,7 @@ class FsAgent {
|
|
|
1268
1278
|
}
|
|
1269
1279
|
}
|
|
1270
1280
|
_persistCurrentRef(ref) {
|
|
1281
|
+
this._rememberState(ref);
|
|
1271
1282
|
try {
|
|
1272
1283
|
writeFileSync(
|
|
1273
1284
|
join(this._rootPath, AGENT_STATE_FILE),
|
|
@@ -2378,6 +2389,28 @@ ${err.stack}` : String(err);
|
|
|
2378
2389
|
* its own pushes, and the states it adopts from theirs.
|
|
2379
2390
|
* @param tree - The tree that just went out, or was adopted as ours.
|
|
2380
2391
|
*/
|
|
2392
|
+
/**
|
|
2393
|
+
* Records a state this node is now in.
|
|
2394
|
+
* @param ref - The content ref of that state.
|
|
2395
|
+
*/
|
|
2396
|
+
_rememberState(ref) {
|
|
2397
|
+
if (this._stateHistory.includes(ref)) return;
|
|
2398
|
+
this._stateHistory.push(ref);
|
|
2399
|
+
if (this._stateHistory.length > STATE_HISTORY_MAX) {
|
|
2400
|
+
this._stateHistory.shift();
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
/**
|
|
2404
|
+
* Whether a push comes from a sender this node has already moved past.
|
|
2405
|
+
* @param predecessorRefs - What the push declares it descends from.
|
|
2406
|
+
* @returns True when every declared parent is a state this node has left.
|
|
2407
|
+
*/
|
|
2408
|
+
_senderIsBehind(predecessorRefs) {
|
|
2409
|
+
if (predecessorRefs.length === 0) return false;
|
|
2410
|
+
return predecessorRefs.every(
|
|
2411
|
+
(ref) => ref !== this._currentRef && ref !== this._lastAppliedRef && this._stateHistory.includes(ref)
|
|
2412
|
+
);
|
|
2413
|
+
}
|
|
2381
2414
|
_rememberAnnounced(tree) {
|
|
2382
2415
|
this._announcedFiles.clear();
|
|
2383
2416
|
for (const path of this._getFileContentMap(tree).keys()) {
|
|
@@ -2549,6 +2582,12 @@ ${err.stack}` : String(err);
|
|
|
2549
2582
|
(r) => r !== void 0
|
|
2550
2583
|
);
|
|
2551
2584
|
const senderSawMyState = !ancestryIsCarried || !declaresAncestry || statesIAmIn.some((r) => predecessorRefs.includes(r));
|
|
2585
|
+
if (ancestryIsCarried && declaresAncestry && this._senderIsBehind(predecessorRefs)) {
|
|
2586
|
+
console.warn(
|
|
2587
|
+
`[FsAgent] ref=${treeRef.slice(0, 8)}… descends from a state this node has already left — ignoring, the sender will catch up and re-push.`
|
|
2588
|
+
);
|
|
2589
|
+
return;
|
|
2590
|
+
}
|
|
2552
2591
|
const withholdPrune = restoreOptions?.cleanTarget && (ancestryExpected && !declaresAncestry || !senderSawMyState);
|
|
2553
2592
|
const applyOptions = withholdPrune ? { ...restoreOptions, cleanTarget: false } : restoreOptions;
|
|
2554
2593
|
if (applyOptions !== restoreOptions) {
|