@peerbit/shared-log 16.0.29 → 16.0.30
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/README.md +70 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +223 -42
- package/dist/src/index.js.map +1 -1
- package/package.json +18 -18
- package/src/index.ts +228 -56
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peerbit/shared-log",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.30",
|
|
4
4
|
"description": "Shared log",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -62,37 +62,37 @@
|
|
|
62
62
|
"pidusage": "^4.0.1",
|
|
63
63
|
"pino": "^9.4.0",
|
|
64
64
|
"uint8arrays": "^5.1.0",
|
|
65
|
-
"@peerbit/blocks": "4.3.0",
|
|
66
|
-
"@peerbit/blocks-interface": "2.2.0",
|
|
67
65
|
"@peerbit/any-store": "2.2.17",
|
|
68
|
-
"@peerbit/
|
|
66
|
+
"@peerbit/blocks": "4.3.1",
|
|
69
67
|
"@peerbit/crypto": "3.1.6",
|
|
70
|
-
"@peerbit/
|
|
68
|
+
"@peerbit/blocks-interface": "2.2.1",
|
|
69
|
+
"@peerbit/cache": "3.1.1",
|
|
71
70
|
"@peerbit/indexer-sqlite3": "3.0.20",
|
|
72
|
-
"@peerbit/logger": "2.0.2",
|
|
73
|
-
"@peerbit/indexer-interface": "3.0.13",
|
|
74
|
-
"@peerbit/pubsub": "5.4.5",
|
|
75
|
-
"@peerbit/rpc": "6.1.27",
|
|
76
71
|
"@peerbit/diagnostics": "0.0.1",
|
|
72
|
+
"@peerbit/log": "6.2.33",
|
|
73
|
+
"@peerbit/program": "6.0.60",
|
|
74
|
+
"@peerbit/pubsub": "5.4.6",
|
|
75
|
+
"@peerbit/pubsub-interface": "5.2.2",
|
|
76
|
+
"@peerbit/logger": "2.0.2",
|
|
77
77
|
"@peerbit/riblt": "1.2.0",
|
|
78
|
+
"@peerbit/rpc": "6.1.28",
|
|
78
79
|
"@peerbit/stream-interface": "6.0.16",
|
|
79
|
-
"@peerbit/
|
|
80
|
-
"@peerbit/time": "3.0.1"
|
|
81
|
-
"@peerbit/program": "6.0.59"
|
|
80
|
+
"@peerbit/indexer-interface": "3.0.13",
|
|
81
|
+
"@peerbit/time": "3.0.1"
|
|
82
82
|
},
|
|
83
83
|
"optionalDependencies": {
|
|
84
|
-
"@peerbit/
|
|
85
|
-
"@peerbit/
|
|
84
|
+
"@peerbit/shared-log-rust": "0.1.7",
|
|
85
|
+
"@peerbit/native-backbone": "0.2.15"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@types/libsodium-wrappers": "^0.7.14",
|
|
89
89
|
"@types/pidusage": "^2.0.5",
|
|
90
90
|
"uuid": "^11.1.1",
|
|
91
|
-
"@peerbit/any-store-rust": "0.1.7",
|
|
92
|
-
"@peerbit/indexer-simple": "1.2.17",
|
|
93
91
|
"@peerbit/indexer-rust": "1.0.14",
|
|
94
|
-
"peerbit": "
|
|
95
|
-
"@peerbit/test-utils": "3.1.
|
|
92
|
+
"@peerbit/indexer-simple": "1.2.17",
|
|
93
|
+
"@peerbit/test-utils": "3.1.41",
|
|
94
|
+
"@peerbit/any-store-rust": "0.1.7",
|
|
95
|
+
"peerbit": "5.4.2"
|
|
96
96
|
},
|
|
97
97
|
"repository": {
|
|
98
98
|
"type": "git",
|
package/src/index.ts
CHANGED
|
@@ -564,7 +564,7 @@ const emitAdvisorySyncProfileDuration = (
|
|
|
564
564
|
try {
|
|
565
565
|
emitSyncProfileDuration(profile, startedAt, event);
|
|
566
566
|
} catch {
|
|
567
|
-
//
|
|
567
|
+
// Advisory diagnostics must not change replication or lifecycle behavior.
|
|
568
568
|
}
|
|
569
569
|
};
|
|
570
570
|
|
|
@@ -4033,7 +4033,13 @@ export class SharedLog<
|
|
|
4033
4033
|
this._repairMetrics["join-warmup"].simpleFallbackPasses += 1;
|
|
4034
4034
|
},
|
|
4035
4035
|
sendEntriesSimple: (target, entries, options) =>
|
|
4036
|
-
this.sendRepairEntriesWithTransport(
|
|
4036
|
+
this.sendRepairEntriesWithTransport(
|
|
4037
|
+
target,
|
|
4038
|
+
entries,
|
|
4039
|
+
"simple",
|
|
4040
|
+
options,
|
|
4041
|
+
"join-warmup",
|
|
4042
|
+
),
|
|
4037
4043
|
logError: (error) => logger.error(error),
|
|
4038
4044
|
});
|
|
4039
4045
|
}
|
|
@@ -10639,6 +10645,7 @@ export class SharedLog<
|
|
|
10639
10645
|
isStillCurrent?: () => boolean;
|
|
10640
10646
|
signal?: AbortSignal;
|
|
10641
10647
|
},
|
|
10648
|
+
mode?: RepairDispatchMode,
|
|
10642
10649
|
) {
|
|
10643
10650
|
const isStillCurrent = options?.isStillCurrent ?? (() => true);
|
|
10644
10651
|
if (!isStillCurrent()) {
|
|
@@ -10646,53 +10653,87 @@ export class SharedLog<
|
|
|
10646
10653
|
}
|
|
10647
10654
|
const unknownEntries = new Map<string, RepairDispatchEntry<R>>();
|
|
10648
10655
|
const knownHashes: string[] = [];
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10656
|
+
const profile = this._logProperties?.sync?.profile;
|
|
10657
|
+
const startedAt = syncProfileStart(profile);
|
|
10658
|
+
const inputEntries = profile ? entries.size : 0;
|
|
10659
|
+
let selectedEntries = 0;
|
|
10660
|
+
let lastObservedCurrent = true;
|
|
10661
|
+
let outcome = "stale";
|
|
10662
|
+
try {
|
|
10663
|
+
for (const [hash, entry] of entries) {
|
|
10664
|
+
if (
|
|
10665
|
+
(options?.bypassRecentKnownPeers ||
|
|
10666
|
+
!this.isEntryRecentlyKnownByPeer(
|
|
10667
|
+
hash,
|
|
10668
|
+
target,
|
|
10669
|
+
RECENT_KNOWN_REPAIR_SUPPRESSION_MS,
|
|
10670
|
+
)) &&
|
|
10671
|
+
(options?.bypassKnownPeers || !this.isEntryKnownByPeer(hash, target))
|
|
10672
|
+
) {
|
|
10673
|
+
unknownEntries.set(hash, entry);
|
|
10674
|
+
} else {
|
|
10675
|
+
knownHashes.push(hash);
|
|
10676
|
+
}
|
|
10662
10677
|
}
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
return;
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
return;
|
|
10681
|
-
}
|
|
10682
|
-
|
|
10683
|
-
const syncEntries = this._logProperties?.sync?.priority
|
|
10684
|
-
? (this._coordinates.materializeRepairDispatchEntries(
|
|
10678
|
+
// A custom synchronizer may mutate the Map once it receives it.
|
|
10679
|
+
if (profile) selectedEntries = unknownEntries.size;
|
|
10680
|
+
if (!isStillCurrent()) return;
|
|
10681
|
+
this.clearRepairFrontierHashes(target, knownHashes);
|
|
10682
|
+
if (unknownEntries.size === 0) {
|
|
10683
|
+
outcome = "known-suppressed";
|
|
10684
|
+
return;
|
|
10685
|
+
}
|
|
10686
|
+
if (transport === "simple") {
|
|
10687
|
+
// Observe only checks the lower path already makes, without adding
|
|
10688
|
+
// lifecycle decisions or wrapping the disabled-profiling path.
|
|
10689
|
+
const dispatchIsStillCurrent = profile
|
|
10690
|
+
? () => (lastObservedCurrent = isStillCurrent())
|
|
10691
|
+
: isStillCurrent;
|
|
10692
|
+
// Fallback repair does not wait for the maybe-sync round trip.
|
|
10693
|
+
await this.pushRepairEntries(
|
|
10694
|
+
target,
|
|
10685
10695
|
unknownEntries,
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
|
|
10696
|
+
dispatchIsStillCurrent,
|
|
10697
|
+
options?.signal,
|
|
10698
|
+
);
|
|
10699
|
+
} else {
|
|
10700
|
+
const syncEntries = this._logProperties?.sync?.priority
|
|
10701
|
+
? (this._coordinates.materializeRepairDispatchEntries(
|
|
10702
|
+
unknownEntries,
|
|
10703
|
+
) as unknown as Map<string, SyncEntryCoordinates<R>>)
|
|
10704
|
+
: (unknownEntries as Map<string, SyncEntryCoordinates<R>>);
|
|
10705
|
+
if (!isStillCurrent()) return;
|
|
10706
|
+
await this.syncronizer.onMaybeMissingEntries({
|
|
10707
|
+
entries: syncEntries,
|
|
10708
|
+
targets: [target],
|
|
10709
|
+
signal: options?.signal,
|
|
10710
|
+
});
|
|
10711
|
+
}
|
|
10712
|
+
outcome = !lastObservedCurrent
|
|
10713
|
+
? "stale"
|
|
10714
|
+
: options?.signal?.aborted
|
|
10715
|
+
? "cancelled"
|
|
10716
|
+
: "dispatched";
|
|
10717
|
+
} catch (error) {
|
|
10718
|
+
outcome = "error";
|
|
10719
|
+
throw error;
|
|
10720
|
+
} finally {
|
|
10721
|
+
if (profile) {
|
|
10722
|
+
emitAdvisorySyncProfileDuration(profile, startedAt, {
|
|
10723
|
+
name: "sharedLog.repair.dispatch",
|
|
10724
|
+
component: "shared-log",
|
|
10725
|
+
entries: inputEntries,
|
|
10726
|
+
count: selectedEntries,
|
|
10727
|
+
targets: 1,
|
|
10728
|
+
details: {
|
|
10729
|
+
mode,
|
|
10730
|
+
transport,
|
|
10731
|
+
outcome,
|
|
10732
|
+
knownSuppressedEntries: knownHashes.length,
|
|
10733
|
+
},
|
|
10734
|
+
});
|
|
10735
|
+
}
|
|
10690
10736
|
}
|
|
10691
|
-
await this.syncronizer.onMaybeMissingEntries({
|
|
10692
|
-
entries: syncEntries,
|
|
10693
|
-
targets: [target],
|
|
10694
|
-
signal: options?.signal,
|
|
10695
|
-
});
|
|
10696
10737
|
}
|
|
10697
10738
|
|
|
10698
10739
|
private async sendMaybeMissingEntriesNow(
|
|
@@ -10776,6 +10817,7 @@ export class SharedLog<
|
|
|
10776
10817
|
this.isRepairLifecycleActive(repairLifecycleController),
|
|
10777
10818
|
signal: repairLifecycleController.signal,
|
|
10778
10819
|
},
|
|
10820
|
+
options.mode,
|
|
10779
10821
|
),
|
|
10780
10822
|
).catch((error: any) => logger.error(error));
|
|
10781
10823
|
}
|
|
@@ -11166,6 +11208,7 @@ export class SharedLog<
|
|
|
11166
11208
|
this.isRepairLifecycleActive(repairLifecycleController),
|
|
11167
11209
|
signal: repairLifecycleController.signal,
|
|
11168
11210
|
},
|
|
11211
|
+
options.mode,
|
|
11169
11212
|
),
|
|
11170
11213
|
).catch((error: any) => logger.error(error));
|
|
11171
11214
|
};
|
|
@@ -11309,6 +11352,18 @@ export class SharedLog<
|
|
|
11309
11352
|
repairLifecycleController: AbortController = this._instanceLifecycle
|
|
11310
11353
|
?.ownershipLifecycleController as AbortController,
|
|
11311
11354
|
) {
|
|
11355
|
+
const profile = this._logProperties?.sync?.profile;
|
|
11356
|
+
const startedAt = syncProfileStart(profile);
|
|
11357
|
+
const profileCounts = profile
|
|
11358
|
+
? {
|
|
11359
|
+
passes: 0,
|
|
11360
|
+
inputEntries: 0,
|
|
11361
|
+
nativePasses: 0,
|
|
11362
|
+
repairCandidates: 0,
|
|
11363
|
+
repairBatches: 0,
|
|
11364
|
+
outcome: "stale",
|
|
11365
|
+
}
|
|
11366
|
+
: undefined;
|
|
11312
11367
|
try {
|
|
11313
11368
|
while (this.isRepairLifecycleActive(repairLifecycleController)) {
|
|
11314
11369
|
if (!this.isRepairLifecycleActive(repairLifecycleController)) {
|
|
@@ -11347,8 +11402,10 @@ export class SharedLog<
|
|
|
11347
11402
|
pruneStaleJoinWarmupPeers();
|
|
11348
11403
|
|
|
11349
11404
|
if (pendingModes.size === 0) {
|
|
11405
|
+
if (profileCounts) profileCounts.outcome = "completed";
|
|
11350
11406
|
return;
|
|
11351
11407
|
}
|
|
11408
|
+
if (profileCounts) profileCounts.passes += 1;
|
|
11352
11409
|
|
|
11353
11410
|
const optimisticGidPeersByMode = new Map<
|
|
11354
11411
|
RepairDispatchMode,
|
|
@@ -11447,6 +11504,10 @@ export class SharedLog<
|
|
|
11447
11504
|
}
|
|
11448
11505
|
return;
|
|
11449
11506
|
}
|
|
11507
|
+
if (profileCounts) {
|
|
11508
|
+
profileCounts.repairCandidates += entries.size;
|
|
11509
|
+
profileCounts.repairBatches += 1;
|
|
11510
|
+
}
|
|
11450
11511
|
this.dispatchMaybeMissingEntries(
|
|
11451
11512
|
target,
|
|
11452
11513
|
entries,
|
|
@@ -11513,6 +11574,10 @@ export class SharedLog<
|
|
|
11513
11574
|
residentEntriesByHash &&
|
|
11514
11575
|
!this.hasCustomFindLeaders()
|
|
11515
11576
|
) {
|
|
11577
|
+
if (profileCounts) {
|
|
11578
|
+
profileCounts.nativePasses += 1;
|
|
11579
|
+
profileCounts.inputEntries += residentEntriesByHash.size;
|
|
11580
|
+
}
|
|
11516
11581
|
const repairDispatchPlan = pruneStaleJoinWarmupPeers()
|
|
11517
11582
|
? await this.planResidentRepairDispatchBatch(
|
|
11518
11583
|
{
|
|
@@ -11551,6 +11616,7 @@ export class SharedLog<
|
|
|
11551
11616
|
const entries = await iterator.next(
|
|
11552
11617
|
REPAIR_SWEEP_ENTRY_BATCH_SIZE,
|
|
11553
11618
|
);
|
|
11619
|
+
if (profileCounts) profileCounts.inputEntries += entries.length;
|
|
11554
11620
|
if (!this.isRepairLifecycleActive(repairLifecycleController)) {
|
|
11555
11621
|
return;
|
|
11556
11622
|
}
|
|
@@ -11675,6 +11741,7 @@ export class SharedLog<
|
|
|
11675
11741
|
}
|
|
11676
11742
|
}
|
|
11677
11743
|
} catch (error: any) {
|
|
11744
|
+
if (profileCounts) profileCounts.outcome = "error";
|
|
11678
11745
|
if (
|
|
11679
11746
|
this.isRepairLifecycleActive(repairLifecycleController) &&
|
|
11680
11747
|
!isNotStartedError(error)
|
|
@@ -11696,6 +11763,21 @@ export class SharedLog<
|
|
|
11696
11763
|
void this.runRepairSweep(repairLifecycleController);
|
|
11697
11764
|
}
|
|
11698
11765
|
}
|
|
11766
|
+
if (profileCounts) {
|
|
11767
|
+
emitAdvisorySyncProfileDuration(profile, startedAt, {
|
|
11768
|
+
name: "sharedLog.placement.pass",
|
|
11769
|
+
component: "shared-log",
|
|
11770
|
+
entries: profileCounts.inputEntries,
|
|
11771
|
+
count: profileCounts.repairCandidates,
|
|
11772
|
+
details: {
|
|
11773
|
+
phase: "repair-sweep",
|
|
11774
|
+
outcome: profileCounts.outcome,
|
|
11775
|
+
passes: profileCounts.passes,
|
|
11776
|
+
nativePasses: profileCounts.nativePasses,
|
|
11777
|
+
repairBatches: profileCounts.repairBatches,
|
|
11778
|
+
},
|
|
11779
|
+
});
|
|
11780
|
+
}
|
|
11699
11781
|
}
|
|
11700
11782
|
}
|
|
11701
11783
|
|
|
@@ -21274,10 +21356,11 @@ export class SharedLog<
|
|
|
21274
21356
|
msg.heads.map((head) => head.hash),
|
|
21275
21357
|
);
|
|
21276
21358
|
if (syncProfile) {
|
|
21277
|
-
|
|
21359
|
+
emitAdvisorySyncProfileDuration(syncProfile, rawExistingStartedAt, {
|
|
21278
21360
|
name: "sharedLog.rawReceive.existingHeads",
|
|
21279
21361
|
component: "shared-log",
|
|
21280
21362
|
entries: msg.heads.length,
|
|
21363
|
+
count: rawExistingHashes.size,
|
|
21281
21364
|
messages: 1,
|
|
21282
21365
|
});
|
|
21283
21366
|
}
|
|
@@ -21711,10 +21794,11 @@ export class SharedLog<
|
|
|
21711
21794
|
? undefined
|
|
21712
21795
|
: await this.log.hasMany(headHashes);
|
|
21713
21796
|
if (syncProfile) {
|
|
21714
|
-
|
|
21797
|
+
emitAdvisorySyncProfileDuration(syncProfile, existingStartedAt, {
|
|
21715
21798
|
name: "sharedLog.receive.existingHeads",
|
|
21716
21799
|
component: "shared-log",
|
|
21717
21800
|
entries: heads.length,
|
|
21801
|
+
count: existingHashes?.size,
|
|
21718
21802
|
messages: 1,
|
|
21719
21803
|
details: { rawMaterializedKnownMissing },
|
|
21720
21804
|
});
|
|
@@ -29478,6 +29562,17 @@ export class SharedLog<
|
|
|
29478
29562
|
isOwnershipLifecycleCurrent() &&
|
|
29479
29563
|
[...warmupPeers].every(isCurrentJoinWarmupTarget);
|
|
29480
29564
|
|
|
29565
|
+
const profile = this._logProperties?.sync?.profile;
|
|
29566
|
+
const profileStartedAt = syncProfileStart(profile);
|
|
29567
|
+
const profileCounts = profile
|
|
29568
|
+
? {
|
|
29569
|
+
examinedEntries: 0,
|
|
29570
|
+
repairCandidates: 0,
|
|
29571
|
+
repairBatches: 0,
|
|
29572
|
+
pruneScan: false,
|
|
29573
|
+
outcome: "stale",
|
|
29574
|
+
}
|
|
29575
|
+
: undefined;
|
|
29481
29576
|
try {
|
|
29482
29577
|
const uncheckedDeliver: Map<
|
|
29483
29578
|
string,
|
|
@@ -29501,6 +29596,10 @@ export class SharedLog<
|
|
|
29501
29596
|
: isWarmupTarget
|
|
29502
29597
|
? "join-warmup"
|
|
29503
29598
|
: "join-authoritative";
|
|
29599
|
+
if (profileCounts) {
|
|
29600
|
+
profileCounts.repairCandidates += entries.size;
|
|
29601
|
+
profileCounts.repairBatches += 1;
|
|
29602
|
+
}
|
|
29504
29603
|
this.dispatchMaybeMissingEntries(
|
|
29505
29604
|
target,
|
|
29506
29605
|
entries,
|
|
@@ -29555,6 +29654,7 @@ export class SharedLog<
|
|
|
29555
29654
|
forceFresh: forceFreshDelivery || useJoinWarmupFastPath,
|
|
29556
29655
|
},
|
|
29557
29656
|
)) {
|
|
29657
|
+
if (profileCounts) profileCounts.examinedEntries += 1;
|
|
29558
29658
|
if (
|
|
29559
29659
|
!isOwnershipLifecycleCurrent() ||
|
|
29560
29660
|
(useJoinWarmupFastPath && !areJoinWarmupGenerationsCurrent())
|
|
@@ -29838,6 +29938,7 @@ export class SharedLog<
|
|
|
29838
29938
|
));
|
|
29839
29939
|
|
|
29840
29940
|
if (shouldRunLocalPruneScan) {
|
|
29941
|
+
if (profileCounts) profileCounts.pruneScan = true;
|
|
29841
29942
|
throwIfOwnershipLifecycleInactive();
|
|
29842
29943
|
// Adaptive range changes and fixed zero-width updates can make already-indexed
|
|
29843
29944
|
// local heads prunable even when the incremental rebalance scan misses them
|
|
@@ -29857,6 +29958,7 @@ export class SharedLog<
|
|
|
29857
29958
|
}
|
|
29858
29959
|
}
|
|
29859
29960
|
|
|
29961
|
+
if (profileCounts) profileCounts.outcome = "completed";
|
|
29860
29962
|
return changed;
|
|
29861
29963
|
} catch (error: any) {
|
|
29862
29964
|
if (!isOwnershipLifecycleCurrent()) {
|
|
@@ -29866,8 +29968,27 @@ export class SharedLog<
|
|
|
29866
29968
|
return false; // we are not started yet, so no changes
|
|
29867
29969
|
}
|
|
29868
29970
|
|
|
29971
|
+
if (profileCounts) profileCounts.outcome = "error";
|
|
29869
29972
|
logger.error(error.toString());
|
|
29870
29973
|
throw error;
|
|
29974
|
+
} finally {
|
|
29975
|
+
if (profileCounts) {
|
|
29976
|
+
emitAdvisorySyncProfileDuration(profile, profileStartedAt, {
|
|
29977
|
+
name: "sharedLog.placement.pass",
|
|
29978
|
+
component: "shared-log",
|
|
29979
|
+
entries: profileCounts.examinedEntries,
|
|
29980
|
+
count: profileCounts.repairCandidates,
|
|
29981
|
+
details: {
|
|
29982
|
+
phase: "range-change",
|
|
29983
|
+
outcome: profileCounts.outcome,
|
|
29984
|
+
changes: changes.length,
|
|
29985
|
+
repairBatches: profileCounts.repairBatches,
|
|
29986
|
+
pruneScan: profileCounts.pruneScan,
|
|
29987
|
+
forceFreshDelivery,
|
|
29988
|
+
joinWarmupFastPath: useJoinWarmupFastPath,
|
|
29989
|
+
},
|
|
29990
|
+
});
|
|
29991
|
+
}
|
|
29871
29992
|
}
|
|
29872
29993
|
}
|
|
29873
29994
|
|
|
@@ -29926,6 +30047,15 @@ export class SharedLog<
|
|
|
29926
30047
|
ownershipLifecycleController = this.captureReplicationOwnershipLifecycle(),
|
|
29927
30048
|
rebalanceParticipationDebounced = this.rebalanceParticipationDebounced,
|
|
29928
30049
|
) {
|
|
30050
|
+
const profile = this._isAdaptiveReplicating
|
|
30051
|
+
? this._logProperties?.sync?.profile
|
|
30052
|
+
: undefined;
|
|
30053
|
+
const profileStartedAt = syncProfileStart(profile);
|
|
30054
|
+
const profileDetails:
|
|
30055
|
+
| Record<string, string | number | boolean | undefined>
|
|
30056
|
+
| undefined = profile
|
|
30057
|
+
? { outcome: "stale", idleRemainingMs: 0 }
|
|
30058
|
+
: undefined;
|
|
29929
30059
|
// Stage 3: the lifecycle owns all three identity terms. `lifecycle` may
|
|
29930
30060
|
// go stale later; its deps late-bind to the host, so the debouncer term
|
|
29931
30061
|
// still reads the current host field, and the role term can disagree
|
|
@@ -29965,6 +30095,14 @@ export class SharedLog<
|
|
|
29965
30095
|
|
|
29966
30096
|
if (this._isAdaptiveReplicating) {
|
|
29967
30097
|
if (this.shouldDelayAdaptiveRebalance()) {
|
|
30098
|
+
if (profileDetails) {
|
|
30099
|
+
profileDetails.outcome = "idle-deferred";
|
|
30100
|
+
profileDetails.idleRemainingMs = Math.max(
|
|
30101
|
+
0,
|
|
30102
|
+
this.adaptiveRebalanceIdleMs -
|
|
30103
|
+
(Date.now() - this._lastLocalAppendAt),
|
|
30104
|
+
);
|
|
30105
|
+
}
|
|
29968
30106
|
if (isCurrent()) {
|
|
29969
30107
|
void rebalanceParticipationDebounced?.call();
|
|
29970
30108
|
}
|
|
@@ -29974,11 +30112,17 @@ export class SharedLog<
|
|
|
29974
30112
|
const peers = this.replicationIndex;
|
|
29975
30113
|
const usedMemory = await this.getMemoryUsage();
|
|
29976
30114
|
if (!isCurrent()) return false;
|
|
30115
|
+
if (profileDetails) {
|
|
30116
|
+
profileDetails.storageUsedBytes = usedMemory;
|
|
30117
|
+
profileDetails.storageObjectiveBytes =
|
|
30118
|
+
this.replicationController.maxMemoryLimit;
|
|
30119
|
+
}
|
|
29977
30120
|
this.scheduleReplicationStatusRefreshForStorage(usedMemory);
|
|
29978
30121
|
let dynamicRange = await this.getDynamicRange();
|
|
29979
30122
|
if (!isCurrent()) return false;
|
|
29980
30123
|
|
|
29981
30124
|
if (!dynamicRange) {
|
|
30125
|
+
if (profileDetails) profileDetails.outcome = "not-permitted";
|
|
29982
30126
|
return; // not allowed to replicate
|
|
29983
30127
|
}
|
|
29984
30128
|
|
|
@@ -30005,13 +30149,24 @@ export class SharedLog<
|
|
|
30005
30149
|
const totalParticipation = await this.calculateTotalParticipation();
|
|
30006
30150
|
if (!isCurrent()) return false;
|
|
30007
30151
|
|
|
30152
|
+
const cpuUsage = this.cpuUsage?.value();
|
|
30153
|
+
const stepStartedAt = syncProfileStart(profile);
|
|
30008
30154
|
const newFactor = this.replicationController.step({
|
|
30009
30155
|
memoryUsage: usedMemory,
|
|
30010
30156
|
currentFactor: dynamicRange.widthNormalized,
|
|
30011
30157
|
totalFactor: totalParticipation, // TODO use this._totalParticipation when flakiness is fixed
|
|
30012
30158
|
peerCount: peersSize,
|
|
30013
|
-
cpuUsage
|
|
30159
|
+
cpuUsage,
|
|
30014
30160
|
});
|
|
30161
|
+
if (profileDetails) {
|
|
30162
|
+
profileDetails.preStepMs = stepStartedAt - profileStartedAt;
|
|
30163
|
+
profileDetails.stepMs = syncProfileStart(profile) - stepStartedAt;
|
|
30164
|
+
profileDetails.currentFactor = dynamicRange.widthNormalized;
|
|
30165
|
+
profileDetails.proposedFactor = newFactor;
|
|
30166
|
+
profileDetails.totalFactor = totalParticipation;
|
|
30167
|
+
profileDetails.controllerPeerCount = peersSize;
|
|
30168
|
+
profileDetails.cpuUsage = cpuUsage;
|
|
30169
|
+
}
|
|
30015
30170
|
|
|
30016
30171
|
const absoluteDifference = Math.abs(
|
|
30017
30172
|
dynamicRange.widthNormalized - newFactor,
|
|
@@ -30048,9 +30203,11 @@ export class SharedLog<
|
|
|
30048
30203
|
(await this._isTrustedReplicator(this.node.identity.publicKey));
|
|
30049
30204
|
if (!isCurrent()) return false;
|
|
30050
30205
|
if (!canReplicate) {
|
|
30206
|
+
if (profileDetails) profileDetails.outcome = "not-permitted";
|
|
30051
30207
|
return false;
|
|
30052
30208
|
}
|
|
30053
30209
|
|
|
30210
|
+
const applyStartedAt = syncProfileStart(profile);
|
|
30054
30211
|
await this.startAnnounceReplicating(
|
|
30055
30212
|
[dynamicRange],
|
|
30056
30213
|
{
|
|
@@ -30061,6 +30218,10 @@ export class SharedLog<
|
|
|
30061
30218
|
ownershipLifecycleController,
|
|
30062
30219
|
);
|
|
30063
30220
|
if (!isCurrent()) return false;
|
|
30221
|
+
if (profileDetails) {
|
|
30222
|
+
profileDetails.outcome = "apply-settled";
|
|
30223
|
+
profileDetails.applyMs = syncProfileStart(profile) - applyStartedAt;
|
|
30224
|
+
}
|
|
30064
30225
|
|
|
30065
30226
|
/* await this._updateRole(newRole, onRoleChange); */
|
|
30066
30227
|
if (isCurrent()) {
|
|
@@ -30069,6 +30230,7 @@ export class SharedLog<
|
|
|
30069
30230
|
|
|
30070
30231
|
return true;
|
|
30071
30232
|
} else {
|
|
30233
|
+
if (profileDetails) profileDetails.outcome = "unchanged";
|
|
30072
30234
|
if (isCurrent()) {
|
|
30073
30235
|
void rebalanceParticipationDebounced?.call();
|
|
30074
30236
|
}
|
|
@@ -30078,14 +30240,24 @@ export class SharedLog<
|
|
|
30078
30240
|
return false;
|
|
30079
30241
|
};
|
|
30080
30242
|
|
|
30081
|
-
|
|
30082
|
-
|
|
30083
|
-
|
|
30243
|
+
try {
|
|
30244
|
+
return await fn().catch((error: any) => {
|
|
30245
|
+
if (isNotStartedError(error) || isClosedStoreRace(error)) {
|
|
30246
|
+
if (profileDetails) profileDetails.outcome = "stale";
|
|
30247
|
+
return false;
|
|
30248
|
+
}
|
|
30249
|
+
if (profileDetails) profileDetails.outcome = "error";
|
|
30250
|
+
throw error;
|
|
30251
|
+
});
|
|
30252
|
+
} finally {
|
|
30253
|
+
if (profileDetails) {
|
|
30254
|
+
emitAdvisorySyncProfileDuration(profile, profileStartedAt, {
|
|
30255
|
+
name: "sharedLog.adaptive.rebalance",
|
|
30256
|
+
component: "shared-log",
|
|
30257
|
+
details: profileDetails,
|
|
30258
|
+
});
|
|
30084
30259
|
}
|
|
30085
|
-
|
|
30086
|
-
});
|
|
30087
|
-
|
|
30088
|
-
return resp;
|
|
30260
|
+
}
|
|
30089
30261
|
}
|
|
30090
30262
|
|
|
30091
30263
|
private getDynamicRangeOffset(): NumberFromType<R> {
|