@peerbit/shared-log 13.0.8 → 13.0.10
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/benchmark/adaptive-ingest.d.ts +2 -0
- package/dist/benchmark/adaptive-ingest.d.ts.map +1 -0
- package/dist/benchmark/adaptive-ingest.js +275 -0
- package/dist/benchmark/adaptive-ingest.js.map +1 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +123 -9
- package/dist/src/index.js.map +1 -1
- package/package.json +16 -14
- package/src/index.ts +187 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peerbit/shared-log",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.10",
|
|
4
4
|
"description": "Shared log",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -61,33 +61,35 @@
|
|
|
61
61
|
"pidusage": "^4.0.1",
|
|
62
62
|
"pino": "^9.4.0",
|
|
63
63
|
"uint8arrays": "^5.1.0",
|
|
64
|
-
"@peerbit/log": "6.0.7",
|
|
65
|
-
"@peerbit/logger": "2.0.0",
|
|
66
|
-
"@peerbit/program": "6.0.5",
|
|
67
64
|
"@peerbit/riblt": "1.2.0",
|
|
68
|
-
"@peerbit/
|
|
65
|
+
"@peerbit/log": "6.0.9",
|
|
66
|
+
"@peerbit/program": "6.0.6",
|
|
67
|
+
"@peerbit/rpc": "6.0.9",
|
|
68
|
+
"@peerbit/logger": "2.0.0",
|
|
69
69
|
"@peerbit/any-store": "2.2.5",
|
|
70
|
-
"@peerbit/
|
|
71
|
-
"@peerbit/blocks-interface": "2.0.
|
|
72
|
-
"@peerbit/blocks": "4.0.3",
|
|
70
|
+
"@peerbit/blocks": "4.0.4",
|
|
71
|
+
"@peerbit/blocks-interface": "2.0.2",
|
|
73
72
|
"@peerbit/crypto": "3.0.0",
|
|
74
|
-
"@peerbit/
|
|
73
|
+
"@peerbit/cache": "3.0.0",
|
|
74
|
+
"@peerbit/pubsub": "5.0.4",
|
|
75
75
|
"@peerbit/indexer-interface": "3.0.0",
|
|
76
|
-
"@peerbit/pubsub-interface": "5.0.
|
|
77
|
-
"@peerbit/stream-interface": "6.0.
|
|
76
|
+
"@peerbit/pubsub-interface": "5.0.3",
|
|
77
|
+
"@peerbit/stream-interface": "6.0.2",
|
|
78
78
|
"@peerbit/time": "3.0.0",
|
|
79
|
-
"@peerbit/
|
|
79
|
+
"@peerbit/indexer-sqlite3": "3.0.1"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@types/libsodium-wrappers": "^0.7.14",
|
|
83
83
|
"@types/pidusage": "^2.0.5",
|
|
84
84
|
"uuid": "^10.0.0",
|
|
85
|
-
"@peerbit/test-utils": "3.0.
|
|
85
|
+
"@peerbit/test-utils": "3.0.9"
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
88
|
"clean": "aegir clean",
|
|
89
89
|
"build": "aegir build --no-bundle",
|
|
90
|
+
"benchmark:adaptive-ingest": "node --loader ts-node/esm ./benchmark/adaptive-ingest.ts",
|
|
90
91
|
"test": "aegir test --target node",
|
|
91
|
-
"lint": "aegir lint"
|
|
92
|
+
"lint": "aegir lint",
|
|
93
|
+
"test:cov": "aegir test -t node --cov"
|
|
92
94
|
}
|
|
93
95
|
}
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
type AppendOptions,
|
|
24
24
|
type Change,
|
|
25
25
|
Entry,
|
|
26
|
+
EntryType,
|
|
26
27
|
Log,
|
|
27
28
|
type LogEvents,
|
|
28
29
|
type LogProperties,
|
|
@@ -48,6 +49,7 @@ import {
|
|
|
48
49
|
} from "@peerbit/pubsub-interface";
|
|
49
50
|
import { RPC, type RequestContext } from "@peerbit/rpc";
|
|
50
51
|
import {
|
|
52
|
+
ACK_CONTROL_PRIORITY,
|
|
51
53
|
AcknowledgeDelivery,
|
|
52
54
|
AnyWhere,
|
|
53
55
|
createRequestTransportContext,
|
|
@@ -399,6 +401,7 @@ export type SharedLogOptions<
|
|
|
399
401
|
? I
|
|
400
402
|
: "u32",
|
|
401
403
|
> = {
|
|
404
|
+
appendDurability?: LogProperties<T>["appendDurability"];
|
|
402
405
|
replicate?: ReplicationOptions<R>;
|
|
403
406
|
replicas?: ReplicationLimitsOptions;
|
|
404
407
|
respondToIHaveTimeout?: number;
|
|
@@ -441,6 +444,8 @@ const RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE = 0.01;
|
|
|
441
444
|
const RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE_WITH_CPU_LIMIT = 0.005;
|
|
442
445
|
const RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE_WITH_MEMORY_LIMIT = 0.001;
|
|
443
446
|
const RECALCULATE_PARTICIPATION_RELATIVE_DENOMINATOR_FLOOR = 1e-3;
|
|
447
|
+
const ADAPTIVE_REBALANCE_IDLE_INTERVAL_MULTIPLIER = 5;
|
|
448
|
+
const ADAPTIVE_REBALANCE_MIN_IDLE_AFTER_LOCAL_APPEND_MS = 10_000;
|
|
444
449
|
|
|
445
450
|
const DEFAULT_DISTRIBUTION_DEBOUNCE_TIME = 500;
|
|
446
451
|
const RECENT_REPAIR_DISPATCH_TTL_MS = 5_000;
|
|
@@ -705,6 +710,8 @@ export class SharedLog<
|
|
|
705
710
|
replicas!: ReplicationLimits;
|
|
706
711
|
|
|
707
712
|
private cpuUsage?: CPUUsage;
|
|
713
|
+
private _lastLocalAppendAt!: number;
|
|
714
|
+
private adaptiveRebalanceIdleMs!: number;
|
|
708
715
|
|
|
709
716
|
timeUntilRoleMaturity!: number;
|
|
710
717
|
waitForReplicatorTimeout!: number;
|
|
@@ -1457,6 +1464,71 @@ export class SharedLog<
|
|
|
1457
1464
|
);
|
|
1458
1465
|
}
|
|
1459
1466
|
|
|
1467
|
+
private markLocalAppendActivity(timestamp = Date.now()) {
|
|
1468
|
+
this._lastLocalAppendAt = Math.max(this._lastLocalAppendAt ?? 0, timestamp);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
private shouldDelayAdaptiveRebalance(now = Date.now()) {
|
|
1472
|
+
return (
|
|
1473
|
+
this._isAdaptiveReplicating &&
|
|
1474
|
+
this._lastLocalAppendAt > 0 &&
|
|
1475
|
+
now - this._lastLocalAppendAt < this.adaptiveRebalanceIdleMs
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
private shouldDeferHeadCoordinatePersistence(
|
|
1480
|
+
options?: SharedAppendOptions<T>,
|
|
1481
|
+
) {
|
|
1482
|
+
return (
|
|
1483
|
+
!this._isReplicating &&
|
|
1484
|
+
options?.replicate === false &&
|
|
1485
|
+
options?.target === "none"
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
private async deleteCoordinatesForHashes(hashes: Iterable<string>) {
|
|
1490
|
+
const values = [...new Set([...hashes].filter(Boolean))];
|
|
1491
|
+
if (values.length === 0) {
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
await this.entryCoordinatesIndex.del({
|
|
1495
|
+
query:
|
|
1496
|
+
values.length === 1
|
|
1497
|
+
? { hash: values[0] }
|
|
1498
|
+
: new Or(
|
|
1499
|
+
values.map((hash) => new StringMatch({ key: "hash", value: hash })),
|
|
1500
|
+
),
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
private async ensureCurrentHeadCoordinatesIndexed() {
|
|
1505
|
+
const heads = await this.log.getHeads(true).all();
|
|
1506
|
+
const headsByHash = new Map(heads.map((head) => [head.hash, head]));
|
|
1507
|
+
const indexedHeads = await this.entryCoordinatesIndex
|
|
1508
|
+
.iterate({}, { shape: { hash: true } })
|
|
1509
|
+
.all();
|
|
1510
|
+
const indexedHashes = new Set(indexedHeads.map((entry) => entry.value.hash));
|
|
1511
|
+
const staleHashes = indexedHeads
|
|
1512
|
+
.map((entry) => entry.value.hash)
|
|
1513
|
+
.filter((hash) => !headsByHash.has(hash));
|
|
1514
|
+
|
|
1515
|
+
if (staleHashes.length > 0) {
|
|
1516
|
+
await this.deleteCoordinatesForHashes(staleHashes);
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
for (const head of heads) {
|
|
1520
|
+
if (indexedHashes.has(head.hash)) {
|
|
1521
|
+
continue;
|
|
1522
|
+
}
|
|
1523
|
+
const minReplicas = decodeReplicas(head).getValue(this);
|
|
1524
|
+
await this.findLeaders(
|
|
1525
|
+
await this.createCoordinates(head, minReplicas),
|
|
1526
|
+
head,
|
|
1527
|
+
{ persist: {} },
|
|
1528
|
+
);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1460
1532
|
private async _replicate(
|
|
1461
1533
|
options?: ReplicationOptions<R>,
|
|
1462
1534
|
{
|
|
@@ -2264,6 +2336,8 @@ export class SharedLog<
|
|
|
2264
2336
|
) => void;
|
|
2265
2337
|
} = {},
|
|
2266
2338
|
) {
|
|
2339
|
+
await this.ensureCurrentHeadCoordinatesIndexed();
|
|
2340
|
+
|
|
2267
2341
|
const change = await this.addReplicationRange(
|
|
2268
2342
|
range,
|
|
2269
2343
|
this.node.identity.publicKey,
|
|
@@ -2659,6 +2733,10 @@ export class SharedLog<
|
|
|
2659
2733
|
entry: Entry<T>;
|
|
2660
2734
|
removed: ShallowOrFullEntry<T>[];
|
|
2661
2735
|
}> {
|
|
2736
|
+
if (this._isAdaptiveReplicating) {
|
|
2737
|
+
this.markLocalAppendActivity();
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2662
2740
|
const appendOptions: AppendOptions<T> = { ...options };
|
|
2663
2741
|
const minReplicas = this.getClampedReplicas(
|
|
2664
2742
|
options?.replicas
|
|
@@ -2693,13 +2771,23 @@ export class SharedLog<
|
|
|
2693
2771
|
return options.onChange!(change);
|
|
2694
2772
|
};
|
|
2695
2773
|
}
|
|
2696
|
-
|
|
2697
2774
|
const result = await this.log.append(data, appendOptions);
|
|
2775
|
+
const deferHeadCoordinatePersistence =
|
|
2776
|
+
result.entry.meta.type !== EntryType.CUT &&
|
|
2777
|
+
this.shouldDeferHeadCoordinatePersistence(options);
|
|
2698
2778
|
|
|
2699
2779
|
if (options?.replicate) {
|
|
2700
2780
|
await this.replicate(result.entry, { checkDuplicates: true });
|
|
2701
2781
|
}
|
|
2702
2782
|
|
|
2783
|
+
if (deferHeadCoordinatePersistence) {
|
|
2784
|
+
await this.deleteCoordinatesForHashes([
|
|
2785
|
+
...result.entry.meta.next,
|
|
2786
|
+
...result.removed.map((entry) => entry.hash),
|
|
2787
|
+
]);
|
|
2788
|
+
return result;
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2703
2791
|
const coordinates = await this.createCoordinates(
|
|
2704
2792
|
result.entry,
|
|
2705
2793
|
minReplicasValue,
|
|
@@ -2744,13 +2832,15 @@ export class SharedLog<
|
|
|
2744
2832
|
}
|
|
2745
2833
|
}
|
|
2746
2834
|
|
|
2747
|
-
if (!isLeader) {
|
|
2835
|
+
if (!isLeader && !this.shouldDelayAdaptiveRebalance()) {
|
|
2748
2836
|
this.pruneDebouncedFnAddIfNotKeeping({
|
|
2749
2837
|
key: result.entry.hash,
|
|
2750
2838
|
value: { entry: result.entry, leaders },
|
|
2751
2839
|
});
|
|
2752
2840
|
}
|
|
2753
|
-
this.
|
|
2841
|
+
if (!this._isAdaptiveReplicating) {
|
|
2842
|
+
this.rebalanceParticipationDebounced?.call();
|
|
2843
|
+
}
|
|
2754
2844
|
|
|
2755
2845
|
return result;
|
|
2756
2846
|
}
|
|
@@ -2805,6 +2895,17 @@ export class SharedLog<
|
|
|
2805
2895
|
this._replicatorLivenessCursor = 0;
|
|
2806
2896
|
this._replicatorLivenessFailures = new Map();
|
|
2807
2897
|
this._replicatorLastActivityAt = new Map();
|
|
2898
|
+
this._lastLocalAppendAt = 0;
|
|
2899
|
+
const adaptiveReplicateOptions =
|
|
2900
|
+
options?.replicate && isAdaptiveReplicatorOption(options.replicate)
|
|
2901
|
+
? options.replicate
|
|
2902
|
+
: undefined;
|
|
2903
|
+
this.adaptiveRebalanceIdleMs = Math.max(
|
|
2904
|
+
ADAPTIVE_REBALANCE_MIN_IDLE_AFTER_LOCAL_APPEND_MS,
|
|
2905
|
+
(adaptiveReplicateOptions?.limits?.interval ??
|
|
2906
|
+
RECALCULATE_PARTICIPATION_DEBOUNCE_INTERVAL) *
|
|
2907
|
+
ADAPTIVE_REBALANCE_IDLE_INTERVAL_MULTIPLIER,
|
|
2908
|
+
);
|
|
2808
2909
|
|
|
2809
2910
|
this.openTime = +new Date();
|
|
2810
2911
|
this.oldestOpenTime = this.openTime;
|
|
@@ -2933,10 +3034,10 @@ export class SharedLog<
|
|
|
2933
3034
|
],
|
|
2934
3035
|
})) > 0;
|
|
2935
3036
|
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
3037
|
+
this._gidPeersHistory = new Map();
|
|
3038
|
+
this._requestIPruneSent = new Map();
|
|
3039
|
+
this._requestIPruneResponseReplicatorSet = new Map();
|
|
3040
|
+
this._checkedPruneRetries = new Map();
|
|
2940
3041
|
|
|
2941
3042
|
this.replicationChangeDebounceFn = debounceAggregationChanges<
|
|
2942
3043
|
ReplicationRangeIndexable<R>
|
|
@@ -3549,7 +3650,8 @@ export class SharedLog<
|
|
|
3549
3650
|
// triggering large segment snapshots just to prove liveness.
|
|
3550
3651
|
await this.rpc.send(new ReplicationPingMessage(), {
|
|
3551
3652
|
mode: new AcknowledgeDelivery({ redundancy: 1, to: [publicKey] }),
|
|
3552
|
-
priority:
|
|
3653
|
+
priority: ACK_CONTROL_PRIORITY,
|
|
3654
|
+
responsePriority: ACK_CONTROL_PRIORITY,
|
|
3553
3655
|
});
|
|
3554
3656
|
this.markReplicatorActivity(peerHash);
|
|
3555
3657
|
this._replicatorLivenessFailures.delete(peerHash);
|
|
@@ -3560,6 +3662,15 @@ export class SharedLog<
|
|
|
3560
3662
|
}
|
|
3561
3663
|
}
|
|
3562
3664
|
|
|
3665
|
+
// Relay-backed prod paths can keep a peer subscribed/reachable even if an
|
|
3666
|
+
// ACKed liveness ping gets delayed or dropped under load. Treat observed
|
|
3667
|
+
// topic presence as a positive liveness signal before evicting the peer.
|
|
3668
|
+
if (await this.confirmReplicatorSubscriberPresence(peerHash)) {
|
|
3669
|
+
this.markReplicatorActivity(peerHash);
|
|
3670
|
+
this._replicatorLivenessFailures.delete(peerHash);
|
|
3671
|
+
return;
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3563
3674
|
const failures = (this._replicatorLivenessFailures.get(peerHash) ?? 0) + 1;
|
|
3564
3675
|
this._replicatorLivenessFailures.set(peerHash, failures);
|
|
3565
3676
|
this.scheduleReplicationInfoRequests(publicKey);
|
|
@@ -3575,6 +3686,24 @@ export class SharedLog<
|
|
|
3575
3686
|
await this.evictReplicatorFromLiveness(peerHash, publicKey);
|
|
3576
3687
|
}
|
|
3577
3688
|
|
|
3689
|
+
private async confirmReplicatorSubscriberPresence(peerHash: string) {
|
|
3690
|
+
try {
|
|
3691
|
+
await waitForSubscribers(this.node, peerHash, this.rpc.topic, {
|
|
3692
|
+
signal: this._closeController.signal,
|
|
3693
|
+
timeout: Math.max(
|
|
3694
|
+
1_000,
|
|
3695
|
+
Math.min(5_000, Math.floor(this.waitForReplicatorTimeout / 4)),
|
|
3696
|
+
),
|
|
3697
|
+
});
|
|
3698
|
+
return true;
|
|
3699
|
+
} catch (error) {
|
|
3700
|
+
if (isNotStartedError(error as Error)) {
|
|
3701
|
+
return false;
|
|
3702
|
+
}
|
|
3703
|
+
return false;
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3578
3707
|
async getMemoryUsage() {
|
|
3579
3708
|
return this.log.blocks.size();
|
|
3580
3709
|
/* ((await this.log.entryIndex?.getMemoryUsage()) || 0) */ // + (await this.log.blocks.size())
|
|
@@ -3801,23 +3930,23 @@ export class SharedLog<
|
|
|
3801
3930
|
}
|
|
3802
3931
|
|
|
3803
3932
|
await this.remoteBlocks.stop();
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3933
|
+
this._pendingDeletes.clear();
|
|
3934
|
+
this._pendingIHave.clear();
|
|
3935
|
+
this._checkedPruneRetries.clear();
|
|
3936
|
+
this.latestReplicationInfoMessage.clear();
|
|
3937
|
+
this._gidPeersHistory.clear();
|
|
3938
|
+
this._requestIPruneSent.clear();
|
|
3939
|
+
this._requestIPruneResponseReplicatorSet.clear();
|
|
3940
|
+
// Cancel any pending debounced timers so they can't fire after we've torn down
|
|
3941
|
+
// indexes/RPC state.
|
|
3942
|
+
this.rebalanceParticipationDebounced?.close();
|
|
3943
|
+
this.replicationChangeDebounceFn?.close?.();
|
|
3944
|
+
this.pruneDebouncedFn?.close?.();
|
|
3945
|
+
this.responseToPruneDebouncedFn?.close?.();
|
|
3946
|
+
this.pruneDebouncedFn = undefined as any;
|
|
3947
|
+
this.rebalanceParticipationDebounced = undefined;
|
|
3948
|
+
this._replicationRangeIndex.stop();
|
|
3949
|
+
this._entryCoordinatesIndex.stop();
|
|
3821
3950
|
this._replicationRangeIndex = undefined as any;
|
|
3822
3951
|
this._entryCoordinatesIndex = undefined as any;
|
|
3823
3952
|
|
|
@@ -4602,6 +4731,14 @@ export class SharedLog<
|
|
|
4602
4731
|
},
|
|
4603
4732
|
): Promise<void> {
|
|
4604
4733
|
let entriesToReplicate: Entry<T>[] = [];
|
|
4734
|
+
const localHashes =
|
|
4735
|
+
options?.replicate && this.log.length > 0
|
|
4736
|
+
? await this.log.entryIndex.hasMany(
|
|
4737
|
+
entries.map((element) =>
|
|
4738
|
+
typeof element === "string" ? element : element.hash,
|
|
4739
|
+
),
|
|
4740
|
+
)
|
|
4741
|
+
: new Set<string>();
|
|
4605
4742
|
if (options?.replicate && this.log.length > 0) {
|
|
4606
4743
|
// TODO this block should perhaps be called from a callback on the this.log.join method on all the ignored element because already joined, like "onAlreadyJoined"
|
|
4607
4744
|
|
|
@@ -4609,18 +4746,18 @@ export class SharedLog<
|
|
|
4609
4746
|
// we can not just do the 'join' call because it will ignore the already joined entries
|
|
4610
4747
|
for (const element of entries) {
|
|
4611
4748
|
if (typeof element === "string") {
|
|
4612
|
-
if (
|
|
4749
|
+
if (localHashes.has(element)) {
|
|
4613
4750
|
const entry = await this.log.get(element);
|
|
4614
4751
|
if (entry) {
|
|
4615
4752
|
entriesToReplicate.push(entry);
|
|
4616
4753
|
}
|
|
4617
4754
|
}
|
|
4618
4755
|
} else if (element instanceof Entry) {
|
|
4619
|
-
if (
|
|
4756
|
+
if (localHashes.has(element.hash)) {
|
|
4620
4757
|
entriesToReplicate.push(element);
|
|
4621
4758
|
}
|
|
4622
4759
|
} else {
|
|
4623
|
-
if (
|
|
4760
|
+
if (localHashes.has(element.hash)) {
|
|
4624
4761
|
const entry = await this.log.get(element.hash);
|
|
4625
4762
|
if (entry) {
|
|
4626
4763
|
entriesToReplicate.push(entry);
|
|
@@ -6168,6 +6305,17 @@ export class SharedLog<
|
|
|
6168
6305
|
// update more participation rate to converge to the average expected rate or bounded by
|
|
6169
6306
|
// resources such as memory and or cpu
|
|
6170
6307
|
|
|
6308
|
+
const isClosedStoreRace = (error: any) => {
|
|
6309
|
+
const message =
|
|
6310
|
+
typeof error?.message === "string" ? error.message : String(error);
|
|
6311
|
+
return (
|
|
6312
|
+
this.closed ||
|
|
6313
|
+
message.includes("Iterator is not open") ||
|
|
6314
|
+
message.includes("cannot read after close()") ||
|
|
6315
|
+
message.includes("Database is not open")
|
|
6316
|
+
);
|
|
6317
|
+
};
|
|
6318
|
+
|
|
6171
6319
|
const fn = async () => {
|
|
6172
6320
|
if (this.closed) {
|
|
6173
6321
|
return false;
|
|
@@ -6179,6 +6327,11 @@ export class SharedLog<
|
|
|
6179
6327
|
}
|
|
6180
6328
|
|
|
6181
6329
|
if (this._isAdaptiveReplicating) {
|
|
6330
|
+
if (this.shouldDelayAdaptiveRebalance()) {
|
|
6331
|
+
this.rebalanceParticipationDebounced?.call();
|
|
6332
|
+
return false;
|
|
6333
|
+
}
|
|
6334
|
+
|
|
6182
6335
|
const peers = this.replicationIndex;
|
|
6183
6336
|
const usedMemory = await this.getMemoryUsage();
|
|
6184
6337
|
let dynamicRange = await this.getDynamicRange();
|
|
@@ -6252,7 +6405,12 @@ export class SharedLog<
|
|
|
6252
6405
|
return false;
|
|
6253
6406
|
};
|
|
6254
6407
|
|
|
6255
|
-
const resp = await fn()
|
|
6408
|
+
const resp = await fn().catch((error: any) => {
|
|
6409
|
+
if (isNotStartedError(error) || isClosedStoreRace(error)) {
|
|
6410
|
+
return false;
|
|
6411
|
+
}
|
|
6412
|
+
throw error;
|
|
6413
|
+
});
|
|
6256
6414
|
|
|
6257
6415
|
return resp;
|
|
6258
6416
|
}
|