@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/dist/src/index.js
CHANGED
|
@@ -186,7 +186,7 @@ const emitAdvisorySyncProfileDuration = (profile, startedAt, event) => {
|
|
|
186
186
|
emitSyncProfileDuration(profile, startedAt, event);
|
|
187
187
|
}
|
|
188
188
|
catch {
|
|
189
|
-
//
|
|
189
|
+
// Advisory diagnostics must not change replication or lifecycle behavior.
|
|
190
190
|
}
|
|
191
191
|
};
|
|
192
192
|
const canUseOptionalNativeModuleImports = () => {
|
|
@@ -1964,7 +1964,7 @@ let SharedLog = (() => {
|
|
|
1964
1964
|
bumpSimpleFallbackPasses: () => {
|
|
1965
1965
|
this._repairMetrics["join-warmup"].simpleFallbackPasses += 1;
|
|
1966
1966
|
},
|
|
1967
|
-
sendEntriesSimple: (target, entries, options) => this.sendRepairEntriesWithTransport(target, entries, "simple", options),
|
|
1967
|
+
sendEntriesSimple: (target, entries, options) => this.sendRepairEntriesWithTransport(target, entries, "simple", options, "join-warmup"),
|
|
1968
1968
|
logError: (error) => logger.error(error),
|
|
1969
1969
|
});
|
|
1970
1970
|
}
|
|
@@ -6857,47 +6857,88 @@ let SharedLog = (() => {
|
|
|
6857
6857
|
signal,
|
|
6858
6858
|
});
|
|
6859
6859
|
}
|
|
6860
|
-
async sendRepairEntriesWithTransport(target, entries, transport, options) {
|
|
6860
|
+
async sendRepairEntriesWithTransport(target, entries, transport, options, mode) {
|
|
6861
6861
|
const isStillCurrent = options?.isStillCurrent ?? (() => true);
|
|
6862
6862
|
if (!isStillCurrent()) {
|
|
6863
6863
|
return;
|
|
6864
6864
|
}
|
|
6865
6865
|
const unknownEntries = new Map();
|
|
6866
6866
|
const knownHashes = [];
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6867
|
+
const profile = this._logProperties?.sync?.profile;
|
|
6868
|
+
const startedAt = syncProfileStart(profile);
|
|
6869
|
+
const inputEntries = profile ? entries.size : 0;
|
|
6870
|
+
let selectedEntries = 0;
|
|
6871
|
+
let lastObservedCurrent = true;
|
|
6872
|
+
let outcome = "stale";
|
|
6873
|
+
try {
|
|
6874
|
+
for (const [hash, entry] of entries) {
|
|
6875
|
+
if ((options?.bypassRecentKnownPeers ||
|
|
6876
|
+
!this.isEntryRecentlyKnownByPeer(hash, target, RECENT_KNOWN_REPAIR_SUPPRESSION_MS)) &&
|
|
6877
|
+
(options?.bypassKnownPeers || !this.isEntryKnownByPeer(hash, target))) {
|
|
6878
|
+
unknownEntries.set(hash, entry);
|
|
6879
|
+
}
|
|
6880
|
+
else {
|
|
6881
|
+
knownHashes.push(hash);
|
|
6882
|
+
}
|
|
6883
|
+
}
|
|
6884
|
+
// A custom synchronizer may mutate the Map once it receives it.
|
|
6885
|
+
if (profile)
|
|
6886
|
+
selectedEntries = unknownEntries.size;
|
|
6887
|
+
if (!isStillCurrent())
|
|
6888
|
+
return;
|
|
6889
|
+
this.clearRepairFrontierHashes(target, knownHashes);
|
|
6890
|
+
if (unknownEntries.size === 0) {
|
|
6891
|
+
outcome = "known-suppressed";
|
|
6892
|
+
return;
|
|
6893
|
+
}
|
|
6894
|
+
if (transport === "simple") {
|
|
6895
|
+
// Observe only checks the lower path already makes, without adding
|
|
6896
|
+
// lifecycle decisions or wrapping the disabled-profiling path.
|
|
6897
|
+
const dispatchIsStillCurrent = profile
|
|
6898
|
+
? () => (lastObservedCurrent = isStillCurrent())
|
|
6899
|
+
: isStillCurrent;
|
|
6900
|
+
// Fallback repair does not wait for the maybe-sync round trip.
|
|
6901
|
+
await this.pushRepairEntries(target, unknownEntries, dispatchIsStillCurrent, options?.signal);
|
|
6872
6902
|
}
|
|
6873
6903
|
else {
|
|
6874
|
-
|
|
6904
|
+
const syncEntries = this._logProperties?.sync?.priority
|
|
6905
|
+
? this._coordinates.materializeRepairDispatchEntries(unknownEntries)
|
|
6906
|
+
: unknownEntries;
|
|
6907
|
+
if (!isStillCurrent())
|
|
6908
|
+
return;
|
|
6909
|
+
await this.syncronizer.onMaybeMissingEntries({
|
|
6910
|
+
entries: syncEntries,
|
|
6911
|
+
targets: [target],
|
|
6912
|
+
signal: options?.signal,
|
|
6913
|
+
});
|
|
6875
6914
|
}
|
|
6915
|
+
outcome = !lastObservedCurrent
|
|
6916
|
+
? "stale"
|
|
6917
|
+
: options?.signal?.aborted
|
|
6918
|
+
? "cancelled"
|
|
6919
|
+
: "dispatched";
|
|
6876
6920
|
}
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
this.clearRepairFrontierHashes(target, knownHashes);
|
|
6881
|
-
if (unknownEntries.size === 0) {
|
|
6882
|
-
return;
|
|
6883
|
-
}
|
|
6884
|
-
if (transport === "simple") {
|
|
6885
|
-
// Fallback repair should not depend on the target completing the
|
|
6886
|
-
// RequestMaybeSync -> ResponseMaybeSync round trip.
|
|
6887
|
-
await this.pushRepairEntries(target, unknownEntries, isStillCurrent, options?.signal);
|
|
6888
|
-
return;
|
|
6921
|
+
catch (error) {
|
|
6922
|
+
outcome = "error";
|
|
6923
|
+
throw error;
|
|
6889
6924
|
}
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6925
|
+
finally {
|
|
6926
|
+
if (profile) {
|
|
6927
|
+
emitAdvisorySyncProfileDuration(profile, startedAt, {
|
|
6928
|
+
name: "sharedLog.repair.dispatch",
|
|
6929
|
+
component: "shared-log",
|
|
6930
|
+
entries: inputEntries,
|
|
6931
|
+
count: selectedEntries,
|
|
6932
|
+
targets: 1,
|
|
6933
|
+
details: {
|
|
6934
|
+
mode,
|
|
6935
|
+
transport,
|
|
6936
|
+
outcome,
|
|
6937
|
+
knownSuppressedEntries: knownHashes.length,
|
|
6938
|
+
},
|
|
6939
|
+
});
|
|
6940
|
+
}
|
|
6895
6941
|
}
|
|
6896
|
-
await this.syncronizer.onMaybeMissingEntries({
|
|
6897
|
-
entries: syncEntries,
|
|
6898
|
-
targets: [target],
|
|
6899
|
-
signal: options?.signal,
|
|
6900
|
-
});
|
|
6901
6942
|
}
|
|
6902
6943
|
async sendMaybeMissingEntriesNow(target, entries, options, repairLifecycleController = this._instanceLifecycle
|
|
6903
6944
|
?.ownershipLifecycleController) {
|
|
@@ -6955,7 +6996,7 @@ let SharedLog = (() => {
|
|
|
6955
6996
|
bypassRecentKnownPeers: bypassKnownPeerHints,
|
|
6956
6997
|
isStillCurrent: () => this.isRepairLifecycleActive(repairLifecycleController),
|
|
6957
6998
|
signal: repairLifecycleController.signal,
|
|
6958
|
-
})).catch((error) => logger.error(error));
|
|
6999
|
+
}, options.mode)).catch((error) => logger.error(error));
|
|
6959
7000
|
}
|
|
6960
7001
|
ensureRepairFrontierRunner(mode, target, retryScheduleMs, repairLifecycleController = this._instanceLifecycle
|
|
6961
7002
|
?.ownershipLifecycleController) {
|
|
@@ -7215,7 +7256,7 @@ let SharedLog = (() => {
|
|
|
7215
7256
|
bypassRecentKnownPeers: bypassKnownPeerHints,
|
|
7216
7257
|
isStillCurrent: () => this.isRepairLifecycleActive(repairLifecycleController),
|
|
7217
7258
|
signal: repairLifecycleController.signal,
|
|
7218
|
-
})).catch((error) => logger.error(error));
|
|
7259
|
+
}, options.mode)).catch((error) => logger.error(error));
|
|
7219
7260
|
};
|
|
7220
7261
|
const delayedJoinWarmupRetries = [];
|
|
7221
7262
|
retrySchedule.forEach((delayMs, index) => {
|
|
@@ -7320,6 +7361,18 @@ let SharedLog = (() => {
|
|
|
7320
7361
|
}
|
|
7321
7362
|
async runRepairSweep(repairLifecycleController = this._instanceLifecycle
|
|
7322
7363
|
?.ownershipLifecycleController) {
|
|
7364
|
+
const profile = this._logProperties?.sync?.profile;
|
|
7365
|
+
const startedAt = syncProfileStart(profile);
|
|
7366
|
+
const profileCounts = profile
|
|
7367
|
+
? {
|
|
7368
|
+
passes: 0,
|
|
7369
|
+
inputEntries: 0,
|
|
7370
|
+
nativePasses: 0,
|
|
7371
|
+
repairCandidates: 0,
|
|
7372
|
+
repairBatches: 0,
|
|
7373
|
+
outcome: "stale",
|
|
7374
|
+
}
|
|
7375
|
+
: undefined;
|
|
7323
7376
|
try {
|
|
7324
7377
|
while (this.isRepairLifecycleActive(repairLifecycleController)) {
|
|
7325
7378
|
if (!this.isRepairLifecycleActive(repairLifecycleController)) {
|
|
@@ -7351,8 +7404,12 @@ let SharedLog = (() => {
|
|
|
7351
7404
|
};
|
|
7352
7405
|
pruneStaleJoinWarmupPeers();
|
|
7353
7406
|
if (pendingModes.size === 0) {
|
|
7407
|
+
if (profileCounts)
|
|
7408
|
+
profileCounts.outcome = "completed";
|
|
7354
7409
|
return;
|
|
7355
7410
|
}
|
|
7411
|
+
if (profileCounts)
|
|
7412
|
+
profileCounts.passes += 1;
|
|
7356
7413
|
const optimisticGidPeersByMode = new Map();
|
|
7357
7414
|
const optimisticGidPeersConsumedByMode = new Map();
|
|
7358
7415
|
for (const mode of pendingModes) {
|
|
@@ -7423,6 +7480,10 @@ let SharedLog = (() => {
|
|
|
7423
7480
|
}
|
|
7424
7481
|
return;
|
|
7425
7482
|
}
|
|
7483
|
+
if (profileCounts) {
|
|
7484
|
+
profileCounts.repairCandidates += entries.size;
|
|
7485
|
+
profileCounts.repairBatches += 1;
|
|
7486
|
+
}
|
|
7426
7487
|
this.dispatchMaybeMissingEntries(target, entries, {
|
|
7427
7488
|
bypassRecentDedupe: true,
|
|
7428
7489
|
bypassKnownPeerHints: mode === "churn" ||
|
|
@@ -7473,6 +7534,10 @@ let SharedLog = (() => {
|
|
|
7473
7534
|
if ((this._nativeBackbone ?? this._nativeSharedLogState) &&
|
|
7474
7535
|
residentEntriesByHash &&
|
|
7475
7536
|
!this.hasCustomFindLeaders()) {
|
|
7537
|
+
if (profileCounts) {
|
|
7538
|
+
profileCounts.nativePasses += 1;
|
|
7539
|
+
profileCounts.inputEntries += residentEntriesByHash.size;
|
|
7540
|
+
}
|
|
7476
7541
|
const repairDispatchPlan = pruneStaleJoinWarmupPeers()
|
|
7477
7542
|
? await this.planResidentRepairDispatchBatch({
|
|
7478
7543
|
pendingModes,
|
|
@@ -7505,6 +7570,8 @@ let SharedLog = (() => {
|
|
|
7505
7570
|
!iterator.done() &&
|
|
7506
7571
|
pruneStaleJoinWarmupPeers()) {
|
|
7507
7572
|
const entries = await iterator.next(REPAIR_SWEEP_ENTRY_BATCH_SIZE);
|
|
7573
|
+
if (profileCounts)
|
|
7574
|
+
profileCounts.inputEntries += entries.length;
|
|
7508
7575
|
if (!this.isRepairLifecycleActive(repairLifecycleController)) {
|
|
7509
7576
|
return;
|
|
7510
7577
|
}
|
|
@@ -7619,6 +7686,8 @@ let SharedLog = (() => {
|
|
|
7619
7686
|
}
|
|
7620
7687
|
}
|
|
7621
7688
|
catch (error) {
|
|
7689
|
+
if (profileCounts)
|
|
7690
|
+
profileCounts.outcome = "error";
|
|
7622
7691
|
if (this.isRepairLifecycleActive(repairLifecycleController) &&
|
|
7623
7692
|
!isNotStartedError(error)) {
|
|
7624
7693
|
logger.error(`Repair sweep failed: ${error?.message ?? error}`);
|
|
@@ -7635,6 +7704,21 @@ let SharedLog = (() => {
|
|
|
7635
7704
|
void this.runRepairSweep(repairLifecycleController);
|
|
7636
7705
|
}
|
|
7637
7706
|
}
|
|
7707
|
+
if (profileCounts) {
|
|
7708
|
+
emitAdvisorySyncProfileDuration(profile, startedAt, {
|
|
7709
|
+
name: "sharedLog.placement.pass",
|
|
7710
|
+
component: "shared-log",
|
|
7711
|
+
entries: profileCounts.inputEntries,
|
|
7712
|
+
count: profileCounts.repairCandidates,
|
|
7713
|
+
details: {
|
|
7714
|
+
phase: "repair-sweep",
|
|
7715
|
+
outcome: profileCounts.outcome,
|
|
7716
|
+
passes: profileCounts.passes,
|
|
7717
|
+
nativePasses: profileCounts.nativePasses,
|
|
7718
|
+
repairBatches: profileCounts.repairBatches,
|
|
7719
|
+
},
|
|
7720
|
+
});
|
|
7721
|
+
}
|
|
7638
7722
|
}
|
|
7639
7723
|
}
|
|
7640
7724
|
async pruneDebouncedFnAddIfNotKeeping(args, ownershipLifecycleController = this.captureReplicationOwnershipLifecycle(), additionalCurrentCheck) {
|
|
@@ -14391,10 +14475,11 @@ let SharedLog = (() => {
|
|
|
14391
14475
|
const rawExistingStartedAt = syncProfileStart(syncProfile);
|
|
14392
14476
|
const rawExistingHashes = await this.log.hasMany(msg.heads.map((head) => head.hash));
|
|
14393
14477
|
if (syncProfile) {
|
|
14394
|
-
|
|
14478
|
+
emitAdvisorySyncProfileDuration(syncProfile, rawExistingStartedAt, {
|
|
14395
14479
|
name: "sharedLog.rawReceive.existingHeads",
|
|
14396
14480
|
component: "shared-log",
|
|
14397
14481
|
entries: msg.heads.length,
|
|
14482
|
+
count: rawExistingHashes.size,
|
|
14398
14483
|
messages: 1,
|
|
14399
14484
|
});
|
|
14400
14485
|
}
|
|
@@ -14711,10 +14796,11 @@ let SharedLog = (() => {
|
|
|
14711
14796
|
? undefined
|
|
14712
14797
|
: await this.log.hasMany(headHashes);
|
|
14713
14798
|
if (syncProfile) {
|
|
14714
|
-
|
|
14799
|
+
emitAdvisorySyncProfileDuration(syncProfile, existingStartedAt, {
|
|
14715
14800
|
name: "sharedLog.receive.existingHeads",
|
|
14716
14801
|
component: "shared-log",
|
|
14717
14802
|
entries: heads.length,
|
|
14803
|
+
count: existingHashes?.size,
|
|
14718
14804
|
messages: 1,
|
|
14719
14805
|
details: { rawMaterializedKnownMissing },
|
|
14720
14806
|
});
|
|
@@ -20429,6 +20515,17 @@ let SharedLog = (() => {
|
|
|
20429
20515
|
warmupSessions.get(target);
|
|
20430
20516
|
const areJoinWarmupGenerationsCurrent = () => isOwnershipLifecycleCurrent() &&
|
|
20431
20517
|
[...warmupPeers].every(isCurrentJoinWarmupTarget);
|
|
20518
|
+
const profile = this._logProperties?.sync?.profile;
|
|
20519
|
+
const profileStartedAt = syncProfileStart(profile);
|
|
20520
|
+
const profileCounts = profile
|
|
20521
|
+
? {
|
|
20522
|
+
examinedEntries: 0,
|
|
20523
|
+
repairCandidates: 0,
|
|
20524
|
+
repairBatches: 0,
|
|
20525
|
+
pruneScan: false,
|
|
20526
|
+
outcome: "stale",
|
|
20527
|
+
}
|
|
20528
|
+
: undefined;
|
|
20432
20529
|
try {
|
|
20433
20530
|
const uncheckedDeliver = new Map();
|
|
20434
20531
|
const flushUncheckedDeliverTarget = (target) => {
|
|
@@ -20449,6 +20546,10 @@ let SharedLog = (() => {
|
|
|
20449
20546
|
: isWarmupTarget
|
|
20450
20547
|
? "join-warmup"
|
|
20451
20548
|
: "join-authoritative";
|
|
20549
|
+
if (profileCounts) {
|
|
20550
|
+
profileCounts.repairCandidates += entries.size;
|
|
20551
|
+
profileCounts.repairBatches += 1;
|
|
20552
|
+
}
|
|
20452
20553
|
this.dispatchMaybeMissingEntries(target, entries, {
|
|
20453
20554
|
bypassRecentDedupe: isWarmupTarget || forceFreshDelivery,
|
|
20454
20555
|
bypassKnownPeerHints: forceFreshDelivery ||
|
|
@@ -20487,6 +20588,8 @@ let SharedLog = (() => {
|
|
|
20487
20588
|
for await (const entryReplicated of toRebalance(immediateRebalanceChanges, this.entryCoordinatesIndex, this.recentlyRebalanced, {
|
|
20488
20589
|
forceFresh: forceFreshDelivery || useJoinWarmupFastPath,
|
|
20489
20590
|
})) {
|
|
20591
|
+
if (profileCounts)
|
|
20592
|
+
profileCounts.examinedEntries += 1;
|
|
20490
20593
|
if (!isOwnershipLifecycleCurrent() ||
|
|
20491
20594
|
(useJoinWarmupFastPath && !areJoinWarmupGenerationsCurrent())) {
|
|
20492
20595
|
break;
|
|
@@ -20683,6 +20786,8 @@ let SharedLog = (() => {
|
|
|
20683
20786
|
change.type === "removed" ||
|
|
20684
20787
|
change.type === "replaced"));
|
|
20685
20788
|
if (shouldRunLocalPruneScan) {
|
|
20789
|
+
if (profileCounts)
|
|
20790
|
+
profileCounts.pruneScan = true;
|
|
20686
20791
|
throwIfOwnershipLifecycleInactive();
|
|
20687
20792
|
// Adaptive range changes and fixed zero-width updates can make already-indexed
|
|
20688
20793
|
// local heads prunable even when the incremental rebalance scan misses them
|
|
@@ -20701,6 +20806,8 @@ let SharedLog = (() => {
|
|
|
20701
20806
|
return false;
|
|
20702
20807
|
}
|
|
20703
20808
|
}
|
|
20809
|
+
if (profileCounts)
|
|
20810
|
+
profileCounts.outcome = "completed";
|
|
20704
20811
|
return changed;
|
|
20705
20812
|
}
|
|
20706
20813
|
catch (error) {
|
|
@@ -20710,9 +20817,30 @@ let SharedLog = (() => {
|
|
|
20710
20817
|
if (isNotStartedError(error)) {
|
|
20711
20818
|
return false; // we are not started yet, so no changes
|
|
20712
20819
|
}
|
|
20820
|
+
if (profileCounts)
|
|
20821
|
+
profileCounts.outcome = "error";
|
|
20713
20822
|
logger.error(error.toString());
|
|
20714
20823
|
throw error;
|
|
20715
20824
|
}
|
|
20825
|
+
finally {
|
|
20826
|
+
if (profileCounts) {
|
|
20827
|
+
emitAdvisorySyncProfileDuration(profile, profileStartedAt, {
|
|
20828
|
+
name: "sharedLog.placement.pass",
|
|
20829
|
+
component: "shared-log",
|
|
20830
|
+
entries: profileCounts.examinedEntries,
|
|
20831
|
+
count: profileCounts.repairCandidates,
|
|
20832
|
+
details: {
|
|
20833
|
+
phase: "range-change",
|
|
20834
|
+
outcome: profileCounts.outcome,
|
|
20835
|
+
changes: changes.length,
|
|
20836
|
+
repairBatches: profileCounts.repairBatches,
|
|
20837
|
+
pruneScan: profileCounts.pruneScan,
|
|
20838
|
+
forceFreshDelivery,
|
|
20839
|
+
joinWarmupFastPath: useJoinWarmupFastPath,
|
|
20840
|
+
},
|
|
20841
|
+
});
|
|
20842
|
+
}
|
|
20843
|
+
}
|
|
20716
20844
|
}
|
|
20717
20845
|
async _onUnsubscription(evt) {
|
|
20718
20846
|
logger.trace(`Peer disconnected '${evt.detail.from.hashcode()}' from '${JSON.stringify(evt.detail.topics.map((x) => x))} '`);
|
|
@@ -20741,6 +20869,13 @@ let SharedLog = (() => {
|
|
|
20741
20869
|
await this.handleSubscriptionChange(evt.detail.from, evt.detail.topics, true, subscriptionEpoch, evt.detail.session);
|
|
20742
20870
|
}
|
|
20743
20871
|
async rebalanceParticipation(ownershipLifecycleController = this.captureReplicationOwnershipLifecycle(), rebalanceParticipationDebounced = this.rebalanceParticipationDebounced) {
|
|
20872
|
+
const profile = this._isAdaptiveReplicating
|
|
20873
|
+
? this._logProperties?.sync?.profile
|
|
20874
|
+
: undefined;
|
|
20875
|
+
const profileStartedAt = syncProfileStart(profile);
|
|
20876
|
+
const profileDetails = profile
|
|
20877
|
+
? { outcome: "stale", idleRemainingMs: 0 }
|
|
20878
|
+
: undefined;
|
|
20744
20879
|
// Stage 3: the lifecycle owns all three identity terms. `lifecycle` may
|
|
20745
20880
|
// go stale later; its deps late-bind to the host, so the debouncer term
|
|
20746
20881
|
// still reads the current host field, and the role term can disagree
|
|
@@ -20772,6 +20907,11 @@ let SharedLog = (() => {
|
|
|
20772
20907
|
}
|
|
20773
20908
|
if (this._isAdaptiveReplicating) {
|
|
20774
20909
|
if (this.shouldDelayAdaptiveRebalance()) {
|
|
20910
|
+
if (profileDetails) {
|
|
20911
|
+
profileDetails.outcome = "idle-deferred";
|
|
20912
|
+
profileDetails.idleRemainingMs = Math.max(0, this.adaptiveRebalanceIdleMs -
|
|
20913
|
+
(Date.now() - this._lastLocalAppendAt));
|
|
20914
|
+
}
|
|
20775
20915
|
if (isCurrent()) {
|
|
20776
20916
|
void rebalanceParticipationDebounced?.call();
|
|
20777
20917
|
}
|
|
@@ -20781,11 +20921,18 @@ let SharedLog = (() => {
|
|
|
20781
20921
|
const usedMemory = await this.getMemoryUsage();
|
|
20782
20922
|
if (!isCurrent())
|
|
20783
20923
|
return false;
|
|
20924
|
+
if (profileDetails) {
|
|
20925
|
+
profileDetails.storageUsedBytes = usedMemory;
|
|
20926
|
+
profileDetails.storageObjectiveBytes =
|
|
20927
|
+
this.replicationController.maxMemoryLimit;
|
|
20928
|
+
}
|
|
20784
20929
|
this.scheduleReplicationStatusRefreshForStorage(usedMemory);
|
|
20785
20930
|
let dynamicRange = await this.getDynamicRange();
|
|
20786
20931
|
if (!isCurrent())
|
|
20787
20932
|
return false;
|
|
20788
20933
|
if (!dynamicRange) {
|
|
20934
|
+
if (profileDetails)
|
|
20935
|
+
profileDetails.outcome = "not-permitted";
|
|
20789
20936
|
return; // not allowed to replicate
|
|
20790
20937
|
}
|
|
20791
20938
|
if (this.replicationController.maxMemoryLimit != null &&
|
|
@@ -20805,13 +20952,24 @@ let SharedLog = (() => {
|
|
|
20805
20952
|
const totalParticipation = await this.calculateTotalParticipation();
|
|
20806
20953
|
if (!isCurrent())
|
|
20807
20954
|
return false;
|
|
20955
|
+
const cpuUsage = this.cpuUsage?.value();
|
|
20956
|
+
const stepStartedAt = syncProfileStart(profile);
|
|
20808
20957
|
const newFactor = this.replicationController.step({
|
|
20809
20958
|
memoryUsage: usedMemory,
|
|
20810
20959
|
currentFactor: dynamicRange.widthNormalized,
|
|
20811
20960
|
totalFactor: totalParticipation, // TODO use this._totalParticipation when flakiness is fixed
|
|
20812
20961
|
peerCount: peersSize,
|
|
20813
|
-
cpuUsage
|
|
20962
|
+
cpuUsage,
|
|
20814
20963
|
});
|
|
20964
|
+
if (profileDetails) {
|
|
20965
|
+
profileDetails.preStepMs = stepStartedAt - profileStartedAt;
|
|
20966
|
+
profileDetails.stepMs = syncProfileStart(profile) - stepStartedAt;
|
|
20967
|
+
profileDetails.currentFactor = dynamicRange.widthNormalized;
|
|
20968
|
+
profileDetails.proposedFactor = newFactor;
|
|
20969
|
+
profileDetails.totalFactor = totalParticipation;
|
|
20970
|
+
profileDetails.controllerPeerCount = peersSize;
|
|
20971
|
+
profileDetails.cpuUsage = cpuUsage;
|
|
20972
|
+
}
|
|
20815
20973
|
const absoluteDifference = Math.abs(dynamicRange.widthNormalized - newFactor);
|
|
20816
20974
|
const relativeDifference = absoluteDifference /
|
|
20817
20975
|
Math.max(dynamicRange.widthNormalized, RECALCULATE_PARTICIPATION_RELATIVE_DENOMINATOR_FLOOR);
|
|
@@ -20839,8 +20997,11 @@ let SharedLog = (() => {
|
|
|
20839
20997
|
if (!isCurrent())
|
|
20840
20998
|
return false;
|
|
20841
20999
|
if (!canReplicate) {
|
|
21000
|
+
if (profileDetails)
|
|
21001
|
+
profileDetails.outcome = "not-permitted";
|
|
20842
21002
|
return false;
|
|
20843
21003
|
}
|
|
21004
|
+
const applyStartedAt = syncProfileStart(profile);
|
|
20844
21005
|
await this.startAnnounceReplicating([dynamicRange], {
|
|
20845
21006
|
checkDuplicates: false,
|
|
20846
21007
|
reset: false,
|
|
@@ -20848,6 +21009,10 @@ let SharedLog = (() => {
|
|
|
20848
21009
|
}, ownershipLifecycleController);
|
|
20849
21010
|
if (!isCurrent())
|
|
20850
21011
|
return false;
|
|
21012
|
+
if (profileDetails) {
|
|
21013
|
+
profileDetails.outcome = "apply-settled";
|
|
21014
|
+
profileDetails.applyMs = syncProfileStart(profile) - applyStartedAt;
|
|
21015
|
+
}
|
|
20851
21016
|
/* await this._updateRole(newRole, onRoleChange); */
|
|
20852
21017
|
if (isCurrent()) {
|
|
20853
21018
|
void rebalanceParticipationDebounced?.call();
|
|
@@ -20855,6 +21020,8 @@ let SharedLog = (() => {
|
|
|
20855
21020
|
return true;
|
|
20856
21021
|
}
|
|
20857
21022
|
else {
|
|
21023
|
+
if (profileDetails)
|
|
21024
|
+
profileDetails.outcome = "unchanged";
|
|
20858
21025
|
if (isCurrent()) {
|
|
20859
21026
|
void rebalanceParticipationDebounced?.call();
|
|
20860
21027
|
}
|
|
@@ -20863,13 +21030,27 @@ let SharedLog = (() => {
|
|
|
20863
21030
|
}
|
|
20864
21031
|
return false;
|
|
20865
21032
|
};
|
|
20866
|
-
|
|
20867
|
-
|
|
20868
|
-
|
|
21033
|
+
try {
|
|
21034
|
+
return await fn().catch((error) => {
|
|
21035
|
+
if (isNotStartedError(error) || isClosedStoreRace(error)) {
|
|
21036
|
+
if (profileDetails)
|
|
21037
|
+
profileDetails.outcome = "stale";
|
|
21038
|
+
return false;
|
|
21039
|
+
}
|
|
21040
|
+
if (profileDetails)
|
|
21041
|
+
profileDetails.outcome = "error";
|
|
21042
|
+
throw error;
|
|
21043
|
+
});
|
|
21044
|
+
}
|
|
21045
|
+
finally {
|
|
21046
|
+
if (profileDetails) {
|
|
21047
|
+
emitAdvisorySyncProfileDuration(profile, profileStartedAt, {
|
|
21048
|
+
name: "sharedLog.adaptive.rebalance",
|
|
21049
|
+
component: "shared-log",
|
|
21050
|
+
details: profileDetails,
|
|
21051
|
+
});
|
|
20869
21052
|
}
|
|
20870
|
-
|
|
20871
|
-
});
|
|
20872
|
-
return resp;
|
|
21053
|
+
}
|
|
20873
21054
|
}
|
|
20874
21055
|
getDynamicRangeOffset() {
|
|
20875
21056
|
const options = this._logProperties
|