sliftutils 1.7.26 → 1.7.27
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/index.d.ts
CHANGED
|
@@ -3330,6 +3330,11 @@ declare module "sliftutils/storage/remoteStorage/deployTakeover" {
|
|
|
3330
3330
|
/** The middle-window alternate port of an active remap. The OTHER process of the takeover lives on
|
|
3331
3331
|
* this port on OUR machine (same disk!), so sources pointing at it are self, never sync targets. */
|
|
3332
3332
|
export declare function getTakeoverAltPort(): number | undefined;
|
|
3333
|
+
/** For the dying process of a takeover: our own process's data ends at the write handoff - fast
|
|
3334
|
+
* writes must be on disk by then. Undefined for the successor and in normal operation. Both
|
|
3335
|
+
* processes share the config identity (all self windows look like "ours" to both), so this is
|
|
3336
|
+
* the only way the dying side knows the post-handoff windows belong to the other process. */
|
|
3337
|
+
export declare function getOwnWindowEndClip(): number | undefined;
|
|
3333
3338
|
/** How long to wait between main-port acquisition attempts: tight around the predecessor's
|
|
3334
3339
|
* scheduled death (when the port actually frees), relaxed otherwise. */
|
|
3335
3340
|
export declare function getMainPortAcquireDelay(): number;
|
package/package.json
CHANGED
|
@@ -23,6 +23,11 @@ export declare function getTakeoverStamp(): string | undefined;
|
|
|
23
23
|
/** The middle-window alternate port of an active remap. The OTHER process of the takeover lives on
|
|
24
24
|
* this port on OUR machine (same disk!), so sources pointing at it are self, never sync targets. */
|
|
25
25
|
export declare function getTakeoverAltPort(): number | undefined;
|
|
26
|
+
/** For the dying process of a takeover: our own process's data ends at the write handoff - fast
|
|
27
|
+
* writes must be on disk by then. Undefined for the successor and in normal operation. Both
|
|
28
|
+
* processes share the config identity (all self windows look like "ours" to both), so this is
|
|
29
|
+
* the only way the dying side knows the post-handoff windows belong to the other process. */
|
|
30
|
+
export declare function getOwnWindowEndClip(): number | undefined;
|
|
26
31
|
/** How long to wait between main-port acquisition attempts: tight around the predecessor's
|
|
27
32
|
* scheduled death (when the port actually frees), relaxed otherwise. */
|
|
28
33
|
export declare function getMainPortAcquireDelay(): number;
|
|
@@ -416,6 +416,18 @@ export function getTakeoverAltPort(): number | undefined {
|
|
|
416
416
|
return current.remap?.altPort;
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
+
/** For the dying process of a takeover: our own process's data ends at the write handoff - fast
|
|
420
|
+
* writes must be on disk by then. Undefined for the successor and in normal operation. Both
|
|
421
|
+
* processes share the config identity (all self windows look like "ours" to both), so this is
|
|
422
|
+
* the only way the dying side knows the post-handoff windows belong to the other process. */
|
|
423
|
+
export function getOwnWindowEndClip(): number | undefined {
|
|
424
|
+
let dying = current.dying;
|
|
425
|
+
if (!dying) return undefined;
|
|
426
|
+
let remap = current.remap;
|
|
427
|
+
if (remap) return remap.boundaryA;
|
|
428
|
+
return dying.successorStart;
|
|
429
|
+
}
|
|
430
|
+
|
|
419
431
|
/** How long to wait between main-port acquisition attempts: tight around the predecessor's
|
|
420
432
|
* scheduled death (when the port actually frees), relaxed otherwise. */
|
|
421
433
|
export function getMainPortAcquireDelay(): number {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
WRITE_PAST_WINDOW_GRACE, STORAGE_WRONG_VALID_WINDOW, STORAGE_WRONG_ROUTE, FULL_ROUTE,
|
|
12
12
|
} from "../IArchives";
|
|
13
13
|
import { ROUTING_FILE, parseRoutingData, parseHostedUrl, buildFileUrl, getConfigVersion, getRoute, routeContains, routeIntersection } from "./remoteConfig";
|
|
14
|
-
import { applyDeployRemap, getTakeoverAltPort, onTakeoverEvent } from "./deployTakeover";
|
|
14
|
+
import { applyDeployRemap, getTakeoverAltPort, getOwnWindowEndClip, onTakeoverEvent } from "./deployTakeover";
|
|
15
15
|
import { createApiArchives } from "./createArchives";
|
|
16
16
|
import type { IStorage } from "../IStorage";
|
|
17
17
|
import type { AccessRequest, TrustRecord } from "./storageController";
|
|
@@ -445,9 +445,36 @@ function computeStorePlan(account: string, bucketName: string, routing: RemoteCo
|
|
|
445
445
|
// Being removed from the config entirely is a valid window of NOTHING ([0, 0]): fast
|
|
446
446
|
// writes flush immediately (nothing may sit in memory on a node that's been cut out),
|
|
447
447
|
// while the disk data and index stay served.
|
|
448
|
+
// Internally every self entry is the SAME store - one process listening on one or more ports
|
|
449
|
+
// (a takeover's alternate-port middle window included). So the disk window merges all
|
|
450
|
+
// contiguous own windows: an options boundary or the port split must never force a pointless
|
|
451
|
+
// internal flush between two windows that are both us. Only the DYING process of a takeover
|
|
452
|
+
// clips its end - from the write handoff on, the data belongs to the successor process.
|
|
453
|
+
let diskWindow: [number, number] = [0, 0];
|
|
454
|
+
if (self) {
|
|
455
|
+
let [start, end] = self.validWindow;
|
|
456
|
+
let merged = true;
|
|
457
|
+
while (merged) {
|
|
458
|
+
merged = false;
|
|
459
|
+
for (let entry of selfEntries) {
|
|
460
|
+
let [entryStart, entryEnd] = entry.validWindow;
|
|
461
|
+
if (entryStart > end || entryEnd < start) continue;
|
|
462
|
+
if (entryStart < start || entryEnd > end) {
|
|
463
|
+
start = Math.min(start, entryStart);
|
|
464
|
+
end = Math.max(end, entryEnd);
|
|
465
|
+
merged = true;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
let clip = getOwnWindowEndClip();
|
|
470
|
+
if (clip !== undefined && clip < end) {
|
|
471
|
+
end = clip;
|
|
472
|
+
}
|
|
473
|
+
diskWindow = [start, end];
|
|
474
|
+
}
|
|
448
475
|
let ownIndexes = new Set(selfIndexes);
|
|
449
476
|
let sourceSpecs: StorePlan["sourceSpecs"] = [{
|
|
450
|
-
validWindow:
|
|
477
|
+
validWindow: diskWindow,
|
|
451
478
|
}];
|
|
452
479
|
if (selfIndex !== -1) {
|
|
453
480
|
for (let i = selfIndex + 1; i < effective.sources.length; i++) {
|