@peerbit/shared-log 12.1.3 → 12.2.0-3333888
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/pid-convergence.d.ts +2 -0
- package/dist/benchmark/pid-convergence.d.ts.map +1 -0
- package/dist/benchmark/pid-convergence.js +138 -0
- package/dist/benchmark/pid-convergence.js.map +1 -0
- package/dist/benchmark/rateless-iblt-sender-startsync.d.ts +2 -0
- package/dist/benchmark/rateless-iblt-sender-startsync.d.ts.map +1 -0
- package/dist/benchmark/rateless-iblt-sender-startsync.js +104 -0
- package/dist/benchmark/rateless-iblt-sender-startsync.js.map +1 -0
- package/dist/benchmark/rateless-iblt-startsync-cache.d.ts +2 -0
- package/dist/benchmark/rateless-iblt-startsync-cache.d.ts.map +1 -0
- package/dist/benchmark/rateless-iblt-startsync-cache.js +112 -0
- package/dist/benchmark/rateless-iblt-startsync-cache.js.map +1 -0
- package/dist/benchmark/sync-catchup.d.ts +3 -0
- package/dist/benchmark/sync-catchup.d.ts.map +1 -0
- package/dist/benchmark/sync-catchup.js +109 -0
- package/dist/benchmark/sync-catchup.js.map +1 -0
- package/dist/src/index.d.ts +10 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +66 -32
- package/dist/src/index.js.map +1 -1
- package/dist/src/like.d.ts +71 -0
- package/dist/src/like.d.ts.map +1 -0
- package/dist/src/like.js +2 -0
- package/dist/src/like.js.map +1 -0
- package/dist/src/sync/index.d.ts +14 -0
- package/dist/src/sync/index.d.ts.map +1 -1
- package/dist/src/sync/rateless-iblt.d.ts +14 -22
- package/dist/src/sync/rateless-iblt.d.ts.map +1 -1
- package/dist/src/sync/rateless-iblt.js +139 -22
- package/dist/src/sync/rateless-iblt.js.map +1 -1
- package/dist/src/sync/simple.d.ts +3 -1
- package/dist/src/sync/simple.d.ts.map +1 -1
- package/dist/src/sync/simple.js +24 -2
- package/dist/src/sync/simple.js.map +1 -1
- package/package.json +20 -20
- package/src/index.ts +95 -37
- package/src/like.ts +84 -0
- package/src/sync/index.ts +19 -0
- package/src/sync/rateless-iblt.ts +193 -40
- package/src/sync/simple.ts +26 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peerbit/shared-log",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.2.0-3333888",
|
|
4
4
|
"description": "Shared log",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -54,35 +54,35 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@dao-xyz/borsh": "^6.0.0",
|
|
56
56
|
"@libp2p/crypto": "^5.1.10",
|
|
57
|
+
"@peerbit/log": "5.0.6-3333888",
|
|
58
|
+
"@peerbit/logger": "2.0.0-3333888",
|
|
59
|
+
"@peerbit/program": "5.6.0-3333888",
|
|
60
|
+
"@peerbit/riblt": "1.2.0-3333888",
|
|
61
|
+
"@peerbit/rpc": "5.4.15-3333888",
|
|
62
|
+
"@peerbit/any-store": "2.2.4-3333888",
|
|
63
|
+
"@peerbit/blocks": "3.1.6-3333888",
|
|
64
|
+
"@peerbit/blocks-interface": "1.5.1-3333888",
|
|
65
|
+
"@peerbit/cache": "2.2.0-3333888",
|
|
66
|
+
"@peerbit/crypto": "2.4.1-3333888",
|
|
67
|
+
"@peerbit/indexer-interface": "2.1.1-3333888",
|
|
68
|
+
"@peerbit/indexer-sqlite3": "2.1.0-3333888",
|
|
69
|
+
"@peerbit/pubsub": "4.1.3-3333888",
|
|
70
|
+
"@peerbit/pubsub-interface": "4.1.1-3333888",
|
|
71
|
+
"@peerbit/stream-interface": "5.3.1-3333888",
|
|
72
|
+
"@peerbit/time": "2.3.0-3333888",
|
|
57
73
|
"json-stringify-deterministic": "^1.0.7",
|
|
58
74
|
"p-each-series": "^3.0.0",
|
|
59
75
|
"p-defer": "^4.0.0",
|
|
60
76
|
"p-queue": "^8.0.1",
|
|
61
77
|
"pidusage": "^4.0.1",
|
|
62
78
|
"pino": "^9.4.0",
|
|
63
|
-
"uint8arrays": "^5.1.0"
|
|
64
|
-
"@peerbit/log": "5.0.5",
|
|
65
|
-
"@peerbit/logger": "2.0.0",
|
|
66
|
-
"@peerbit/program": "5.5.2",
|
|
67
|
-
"@peerbit/rpc": "5.4.14",
|
|
68
|
-
"@peerbit/any-store": "2.2.4",
|
|
69
|
-
"@peerbit/riblt": "1.1.0",
|
|
70
|
-
"@peerbit/blocks": "3.1.6",
|
|
71
|
-
"@peerbit/cache": "2.2.0",
|
|
72
|
-
"@peerbit/blocks-interface": "1.5.1",
|
|
73
|
-
"@peerbit/crypto": "2.4.1",
|
|
74
|
-
"@peerbit/indexer-interface": "2.1.1",
|
|
75
|
-
"@peerbit/indexer-sqlite3": "2.0.2",
|
|
76
|
-
"@peerbit/pubsub": "4.1.3",
|
|
77
|
-
"@peerbit/pubsub-interface": "4.1.1",
|
|
78
|
-
"@peerbit/stream-interface": "5.3.1",
|
|
79
|
-
"@peerbit/time": "2.3.0"
|
|
79
|
+
"uint8arrays": "^5.1.0"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
+
"@peerbit/test-utils": "2.3.15-3333888",
|
|
82
83
|
"@types/libsodium-wrappers": "^0.7.14",
|
|
83
84
|
"@types/pidusage": "^2.0.5",
|
|
84
|
-
"uuid": "^10.0.0"
|
|
85
|
-
"@peerbit/test-utils": "2.3.14"
|
|
85
|
+
"uuid": "^10.0.0"
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
88
|
"clean": "aegir clean",
|
package/src/index.ts
CHANGED
|
@@ -135,7 +135,11 @@ import {
|
|
|
135
135
|
maxReplicas,
|
|
136
136
|
} from "./replication.js";
|
|
137
137
|
import { Observer, Replicator } from "./role.js";
|
|
138
|
-
import type {
|
|
138
|
+
import type {
|
|
139
|
+
SyncOptions,
|
|
140
|
+
SynchronizerConstructor,
|
|
141
|
+
Syncronizer,
|
|
142
|
+
} from "./sync/index.js";
|
|
139
143
|
import { RatelessIBLTSynchronizer } from "./sync/rateless-iblt.js";
|
|
140
144
|
import { SimpleSyncronizer } from "./sync/simple.js";
|
|
141
145
|
import { groupByGid } from "./utils.js";
|
|
@@ -149,6 +153,12 @@ export {
|
|
|
149
153
|
};
|
|
150
154
|
export { type CPUUsage, CPUUsageIntervalLag };
|
|
151
155
|
export * from "./replication.js";
|
|
156
|
+
export type {
|
|
157
|
+
LogLike,
|
|
158
|
+
LogResultsIterator,
|
|
159
|
+
SharedLogLike,
|
|
160
|
+
SharedLogReplicationIndexLike,
|
|
161
|
+
} from "./like.js";
|
|
152
162
|
export {
|
|
153
163
|
type ReplicationRangeIndexable,
|
|
154
164
|
ReplicationRangeIndexableU32,
|
|
@@ -352,6 +362,7 @@ export type SharedLogOptions<
|
|
|
352
362
|
keep?: (
|
|
353
363
|
entry: ShallowOrFullEntry<T> | EntryReplicated<R>,
|
|
354
364
|
) => Promise<boolean> | boolean;
|
|
365
|
+
sync?: SyncOptions<R>;
|
|
355
366
|
syncronizer?: SynchronizerConstructor<R>;
|
|
356
367
|
timeUntilRoleMaturity?: number;
|
|
357
368
|
waitForReplicatorTimeout?: number;
|
|
@@ -365,11 +376,18 @@ export type SharedLogOptions<
|
|
|
365
376
|
export const DEFAULT_MIN_REPLICAS = 2;
|
|
366
377
|
export const WAIT_FOR_REPLICATOR_TIMEOUT = 9000;
|
|
367
378
|
export const WAIT_FOR_ROLE_MATURITY = 5000;
|
|
368
|
-
|
|
379
|
+
// TODO(prune): Investigate if/when a non-zero prune delay is required for correctness
|
|
380
|
+
// (e.g. responsibility/replication-info message reordering in multi-peer scenarios).
|
|
381
|
+
// Prefer making pruning robust without timing-based heuristics.
|
|
382
|
+
export const WAIT_FOR_PRUNE_DELAY = 0;
|
|
369
383
|
const PRUNE_DEBOUNCE_INTERVAL = 500;
|
|
370
384
|
|
|
371
385
|
// DONT SET THIS ANY LOWER, because it will make the pid controller unstable as the system responses are not fast enough to updates from the pid controller
|
|
372
386
|
const RECALCULATE_PARTICIPATION_DEBOUNCE_INTERVAL = 1000;
|
|
387
|
+
const RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE = 0.01;
|
|
388
|
+
const RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE_WITH_CPU_LIMIT = 0.005;
|
|
389
|
+
const RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE_WITH_MEMORY_LIMIT = 0.001;
|
|
390
|
+
const RECALCULATE_PARTICIPATION_RELATIVE_DENOMINATOR_FLOOR = 1e-3;
|
|
373
391
|
|
|
374
392
|
const DEFAULT_DISTRIBUTION_DEBOUNCE_TIME = 500;
|
|
375
393
|
|
|
@@ -606,15 +624,6 @@ export class SharedLog<
|
|
|
606
624
|
) {
|
|
607
625
|
this.rebalanceParticipationDebounced = undefined;
|
|
608
626
|
|
|
609
|
-
// make the rebalancing to respect warmup time
|
|
610
|
-
let intervalTime = interval * 2;
|
|
611
|
-
let timeout = setTimeout(() => {
|
|
612
|
-
intervalTime = interval;
|
|
613
|
-
}, this.timeUntilRoleMaturity);
|
|
614
|
-
this._closeController.signal.addEventListener("abort", () => {
|
|
615
|
-
clearTimeout(timeout);
|
|
616
|
-
});
|
|
617
|
-
|
|
618
627
|
this.rebalanceParticipationDebounced = debounceFixedInterval(
|
|
619
628
|
() => this.rebalanceParticipation(),
|
|
620
629
|
/* Math.max(
|
|
@@ -624,7 +633,7 @@ export class SharedLog<
|
|
|
624
633
|
REBALANCE_DEBOUNCE_INTERVAL
|
|
625
634
|
)
|
|
626
635
|
) */
|
|
627
|
-
|
|
636
|
+
interval, // TODO make this dynamic on the number of replicators
|
|
628
637
|
);
|
|
629
638
|
}
|
|
630
639
|
|
|
@@ -1187,16 +1196,20 @@ export class SharedLog<
|
|
|
1187
1196
|
}
|
|
1188
1197
|
}
|
|
1189
1198
|
|
|
1199
|
+
let prevCountForOwner: number | undefined = undefined;
|
|
1190
1200
|
if (existing.length === 0) {
|
|
1191
|
-
|
|
1201
|
+
prevCountForOwner = await this.replicationIndex.count({
|
|
1192
1202
|
query: new StringMatch({ key: "hash", value: from.hashcode() }),
|
|
1193
1203
|
});
|
|
1194
|
-
isNewReplicator =
|
|
1204
|
+
isNewReplicator = prevCountForOwner === 0;
|
|
1195
1205
|
} else {
|
|
1196
1206
|
isNewReplicator = false;
|
|
1197
1207
|
}
|
|
1198
1208
|
|
|
1199
|
-
if (
|
|
1209
|
+
if (
|
|
1210
|
+
checkDuplicates &&
|
|
1211
|
+
(existing.length > 0 || (prevCountForOwner ?? 0) > 0)
|
|
1212
|
+
) {
|
|
1200
1213
|
let deduplicated: ReplicationRangeIndexable<any>[] = [];
|
|
1201
1214
|
|
|
1202
1215
|
// TODO also deduplicate/de-overlap among the ranges that ought to be inserted?
|
|
@@ -1872,8 +1885,8 @@ export class SharedLog<
|
|
|
1872
1885
|
this.timeUntilRoleMaturity =
|
|
1873
1886
|
options?.timeUntilRoleMaturity ?? WAIT_FOR_ROLE_MATURITY;
|
|
1874
1887
|
this.waitForReplicatorTimeout =
|
|
1875
|
-
options?.waitForReplicatorTimeout
|
|
1876
|
-
this.waitForPruneDelay = options?.waitForPruneDelay
|
|
1888
|
+
options?.waitForReplicatorTimeout ?? WAIT_FOR_REPLICATOR_TIMEOUT;
|
|
1889
|
+
this.waitForPruneDelay = options?.waitForPruneDelay ?? WAIT_FOR_PRUNE_DELAY;
|
|
1877
1890
|
|
|
1878
1891
|
if (this.waitForReplicatorTimeout < this.timeUntilRoleMaturity) {
|
|
1879
1892
|
this.waitForReplicatorTimeout = this.timeUntilRoleMaturity; // does not makes sense to expect a replicator to mature faster than it is reachable
|
|
@@ -2037,6 +2050,7 @@ export class SharedLog<
|
|
|
2037
2050
|
rangeIndex: this._replicationRangeIndex,
|
|
2038
2051
|
rpc: this.rpc,
|
|
2039
2052
|
coordinateToHash: this.coordinateToHash,
|
|
2053
|
+
sync: options?.sync,
|
|
2040
2054
|
});
|
|
2041
2055
|
} else {
|
|
2042
2056
|
if (
|
|
@@ -2048,6 +2062,7 @@ export class SharedLog<
|
|
|
2048
2062
|
rpc: this.rpc,
|
|
2049
2063
|
entryIndex: this.entryCoordinatesIndex,
|
|
2050
2064
|
coordinateToHash: this.coordinateToHash,
|
|
2065
|
+
sync: options?.sync,
|
|
2051
2066
|
});
|
|
2052
2067
|
} else {
|
|
2053
2068
|
if (this.domain.resolution === "u32") {
|
|
@@ -2063,6 +2078,7 @@ export class SharedLog<
|
|
|
2063
2078
|
rangeIndex: this._replicationRangeIndex,
|
|
2064
2079
|
rpc: this.rpc,
|
|
2065
2080
|
coordinateToHash: this.coordinateToHash,
|
|
2081
|
+
sync: options?.sync,
|
|
2066
2082
|
}) as Syncronizer<R>;
|
|
2067
2083
|
}
|
|
2068
2084
|
}
|
|
@@ -2378,15 +2394,35 @@ export class SharedLog<
|
|
|
2378
2394
|
set.add(key);
|
|
2379
2395
|
}
|
|
2380
2396
|
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2397
|
+
if (options?.reachableOnly) {
|
|
2398
|
+
// Prefer the live pubsub subscriber set when filtering reachability.
|
|
2399
|
+
// `uniqueReplicators` is primarily driven by replication messages and can lag during
|
|
2400
|
+
// joins/restarts; using subscribers prevents excluding peers that are reachable but
|
|
2401
|
+
// whose replication ranges were loaded from disk or haven't been processed yet.
|
|
2402
|
+
const subscribers =
|
|
2403
|
+
(await this.node.services.pubsub.getSubscribers(this.topic)) ??
|
|
2404
|
+
undefined;
|
|
2405
|
+
const subscriberHashcodes = subscribers
|
|
2406
|
+
? new Set(subscribers.map((key) => key.hashcode()))
|
|
2407
|
+
: undefined;
|
|
2408
|
+
|
|
2409
|
+
const reachable: string[] = [];
|
|
2410
|
+
const selfHash = this.node.identity.publicKey.hashcode();
|
|
2411
|
+
for (const peer of set) {
|
|
2412
|
+
if (peer === selfHash) {
|
|
2413
|
+
reachable.push(peer);
|
|
2414
|
+
continue;
|
|
2415
|
+
}
|
|
2416
|
+
if (
|
|
2417
|
+
subscriberHashcodes
|
|
2418
|
+
? subscriberHashcodes.has(peer)
|
|
2419
|
+
: this.uniqueReplicators.has(peer)
|
|
2420
|
+
) {
|
|
2421
|
+
reachable.push(peer);
|
|
2422
|
+
}
|
|
2386
2423
|
}
|
|
2424
|
+
return reachable;
|
|
2387
2425
|
}
|
|
2388
|
-
return reachableSet;
|
|
2389
|
-
}
|
|
2390
2426
|
|
|
2391
2427
|
return [...set];
|
|
2392
2428
|
} catch (error) {
|
|
@@ -3126,25 +3162,29 @@ export class SharedLog<
|
|
|
3126
3162
|
},
|
|
3127
3163
|
): Promise<void> {
|
|
3128
3164
|
let entriesToReplicate: Entry<T>[] = [];
|
|
3129
|
-
if (options?.replicate) {
|
|
3165
|
+
if (options?.replicate && this.log.length > 0) {
|
|
3130
3166
|
// 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"
|
|
3131
3167
|
|
|
3132
3168
|
// check which entrise we already have but not are replicating, and replicate them
|
|
3133
3169
|
// we can not just do the 'join' call because it will ignore the already joined entries
|
|
3134
3170
|
for (const element of entries) {
|
|
3135
3171
|
if (typeof element === "string") {
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3172
|
+
if (await this.log.has(element)) {
|
|
3173
|
+
const entry = await this.log.get(element);
|
|
3174
|
+
if (entry) {
|
|
3175
|
+
entriesToReplicate.push(entry);
|
|
3176
|
+
}
|
|
3139
3177
|
}
|
|
3140
3178
|
} else if (element instanceof Entry) {
|
|
3141
3179
|
if (await this.log.has(element.hash)) {
|
|
3142
3180
|
entriesToReplicate.push(element);
|
|
3143
3181
|
}
|
|
3144
3182
|
} else {
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3183
|
+
if (await this.log.has(element.hash)) {
|
|
3184
|
+
const entry = await this.log.get(element.hash);
|
|
3185
|
+
if (entry) {
|
|
3186
|
+
entriesToReplicate.push(entry);
|
|
3187
|
+
}
|
|
3148
3188
|
}
|
|
3149
3189
|
}
|
|
3150
3190
|
}
|
|
@@ -3736,7 +3776,7 @@ export class SharedLog<
|
|
|
3736
3776
|
for (const [k, v] of this._requestIPruneResponseReplicatorSet) {
|
|
3737
3777
|
v.delete(publicKey.hashcode());
|
|
3738
3778
|
if (v.size === 0) {
|
|
3739
|
-
this.
|
|
3779
|
+
this._requestIPruneResponseReplicatorSet.delete(k);
|
|
3740
3780
|
}
|
|
3741
3781
|
}
|
|
3742
3782
|
|
|
@@ -4086,8 +4126,13 @@ export class SharedLog<
|
|
|
4086
4126
|
);
|
|
4087
4127
|
}
|
|
4088
4128
|
|
|
4089
|
-
async waitForPruned(
|
|
4090
|
-
|
|
4129
|
+
async waitForPruned(options?: {
|
|
4130
|
+
timeout?: number;
|
|
4131
|
+
signal?: AbortSignal;
|
|
4132
|
+
delayInterval?: number;
|
|
4133
|
+
timeoutMessage?: string;
|
|
4134
|
+
}) {
|
|
4135
|
+
await waitFor(() => this._pendingDeletes.size === 0, options);
|
|
4091
4136
|
}
|
|
4092
4137
|
|
|
4093
4138
|
async onReplicationChange(
|
|
@@ -4266,11 +4311,24 @@ export class SharedLog<
|
|
|
4266
4311
|
cpuUsage: this.cpuUsage?.value(),
|
|
4267
4312
|
});
|
|
4268
4313
|
|
|
4314
|
+
const absoluteDifference = Math.abs(dynamicRange.widthNormalized - newFactor);
|
|
4269
4315
|
const relativeDifference =
|
|
4270
|
-
|
|
4271
|
-
|
|
4316
|
+
absoluteDifference /
|
|
4317
|
+
Math.max(
|
|
4318
|
+
dynamicRange.widthNormalized,
|
|
4319
|
+
RECALCULATE_PARTICIPATION_RELATIVE_DENOMINATOR_FLOOR,
|
|
4320
|
+
);
|
|
4321
|
+
|
|
4322
|
+
let minRelativeChange = RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE;
|
|
4323
|
+
if (this.replicationController.maxMemoryLimit != null) {
|
|
4324
|
+
minRelativeChange =
|
|
4325
|
+
RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE_WITH_MEMORY_LIMIT;
|
|
4326
|
+
} else if (this.replicationController.maxCPUUsage != null) {
|
|
4327
|
+
minRelativeChange =
|
|
4328
|
+
RECALCULATE_PARTICIPATION_MIN_RELATIVE_CHANGE_WITH_CPU_LIMIT;
|
|
4329
|
+
}
|
|
4272
4330
|
|
|
4273
|
-
if (relativeDifference >
|
|
4331
|
+
if (relativeDifference > minRelativeChange) {
|
|
4274
4332
|
// TODO can not reuse old range, since it will (potentially) affect the index because of sideeffects
|
|
4275
4333
|
dynamicRange = new this.indexableDomain.constructorRange({
|
|
4276
4334
|
offset: dynamicRange.start1,
|
package/src/like.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { PublicSignKey } from "@peerbit/crypto";
|
|
2
|
+
import type {
|
|
3
|
+
CountOptions,
|
|
4
|
+
IndexIterator,
|
|
5
|
+
IterateOptions,
|
|
6
|
+
} from "@peerbit/indexer-interface";
|
|
7
|
+
import type { Entry } from "@peerbit/log";
|
|
8
|
+
import type { ShallowEntry } from "@peerbit/log";
|
|
9
|
+
import type { ReplicationOptions, ReplicationRangeIndexable } from "./index.js";
|
|
10
|
+
|
|
11
|
+
export type LogBlocksLike = {
|
|
12
|
+
has: (hash: string) => Promise<boolean> | boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type LogResultsIterator<T> = {
|
|
16
|
+
close: () => void | Promise<void>;
|
|
17
|
+
next: (amount: number) => T[] | Promise<T[]>;
|
|
18
|
+
done: () => boolean | undefined;
|
|
19
|
+
all: () => T[] | Promise<T[]>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type LogLike<T = any> = {
|
|
23
|
+
idString?: string;
|
|
24
|
+
length: number;
|
|
25
|
+
get: (
|
|
26
|
+
hash: string,
|
|
27
|
+
options?: any,
|
|
28
|
+
) => Promise<Entry<T> | undefined> | Entry<T> | undefined;
|
|
29
|
+
has: (hash: string) => Promise<boolean> | boolean;
|
|
30
|
+
getHeads: (resolve?: boolean) => LogResultsIterator<Entry<T> | ShallowEntry>;
|
|
31
|
+
toArray: () => Promise<Entry<T>[]>;
|
|
32
|
+
blocks?: LogBlocksLike;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type SharedLogReplicationIndexLike<R extends "u32" | "u64" = any> = {
|
|
36
|
+
iterate: (
|
|
37
|
+
request?: IterateOptions,
|
|
38
|
+
) => IndexIterator<ReplicationRangeIndexable<R>, undefined>;
|
|
39
|
+
count: (options?: CountOptions) => Promise<number> | number;
|
|
40
|
+
getSize?: () => Promise<number> | number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type SharedLogLike<T = any, R extends "u32" | "u64" = any> = {
|
|
44
|
+
closed?: boolean;
|
|
45
|
+
events: EventTarget;
|
|
46
|
+
log: LogLike<T>;
|
|
47
|
+
replicationIndex: SharedLogReplicationIndexLike<R>;
|
|
48
|
+
node?: { identity: { publicKey: PublicSignKey } };
|
|
49
|
+
getReplicators: () => Promise<Set<string>>;
|
|
50
|
+
waitForReplicator: (
|
|
51
|
+
publicKey: PublicSignKey,
|
|
52
|
+
options?: {
|
|
53
|
+
eager?: boolean;
|
|
54
|
+
roleAge?: number;
|
|
55
|
+
timeout?: number;
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
},
|
|
58
|
+
) => Promise<void>;
|
|
59
|
+
waitForReplicators: (options?: {
|
|
60
|
+
timeout?: number;
|
|
61
|
+
roleAge?: number;
|
|
62
|
+
coverageThreshold?: number;
|
|
63
|
+
waitForNewPeers?: boolean;
|
|
64
|
+
signal?: AbortSignal;
|
|
65
|
+
}) => Promise<void>;
|
|
66
|
+
replicate: (
|
|
67
|
+
rangeOrEntry?: ReplicationOptions<R> | any,
|
|
68
|
+
options?: {
|
|
69
|
+
reset?: boolean;
|
|
70
|
+
checkDuplicates?: boolean;
|
|
71
|
+
rebalance?: boolean;
|
|
72
|
+
mergeSegments?: boolean;
|
|
73
|
+
},
|
|
74
|
+
) => Promise<void | ReplicationRangeIndexable<R>[]>;
|
|
75
|
+
unreplicate: (rangeOrEntry?: { id: Uint8Array }[]) => Promise<void>;
|
|
76
|
+
calculateCoverage: (options?: {
|
|
77
|
+
start?: number | bigint;
|
|
78
|
+
end?: number | bigint;
|
|
79
|
+
roleAge?: number;
|
|
80
|
+
}) => Promise<number>;
|
|
81
|
+
getMyReplicationSegments: () => Promise<ReplicationRangeIndexable<R>[]>;
|
|
82
|
+
getAllReplicationSegments: () => Promise<ReplicationRangeIndexable<R>[]>;
|
|
83
|
+
close: () => Promise<void | boolean>;
|
|
84
|
+
};
|
package/src/sync/index.ts
CHANGED
|
@@ -8,6 +8,24 @@ import type { Numbers } from "../integers.js";
|
|
|
8
8
|
import type { TransportMessage } from "../message.js";
|
|
9
9
|
import type { EntryReplicated, ReplicationRangeIndexable } from "../ranges.js";
|
|
10
10
|
|
|
11
|
+
export type SyncPriorityFn<R extends "u32" | "u64"> = (
|
|
12
|
+
entry: EntryReplicated<R>,
|
|
13
|
+
) => number;
|
|
14
|
+
|
|
15
|
+
export type SyncOptions<R extends "u32" | "u64"> = {
|
|
16
|
+
/**
|
|
17
|
+
* Higher numbers are synced first.
|
|
18
|
+
* The callback should be fast and side-effect free.
|
|
19
|
+
*/
|
|
20
|
+
priority?: SyncPriorityFn<R>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* When using rateless IBLT sync, optionally pre-sync up to this many
|
|
24
|
+
* high-priority entries using the simple synchronizer.
|
|
25
|
+
*/
|
|
26
|
+
maxSimpleEntries?: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
11
29
|
export type SynchronizerComponents<R extends "u32" | "u64"> = {
|
|
12
30
|
rpc: RPC<TransportMessage, TransportMessage>;
|
|
13
31
|
rangeIndex: Index<ReplicationRangeIndexable<R>, any>;
|
|
@@ -15,6 +33,7 @@ export type SynchronizerComponents<R extends "u32" | "u64"> = {
|
|
|
15
33
|
log: Log<any>;
|
|
16
34
|
coordinateToHash: Cache<string>;
|
|
17
35
|
numbers: Numbers<R>;
|
|
36
|
+
sync?: SyncOptions<R>;
|
|
18
37
|
};
|
|
19
38
|
export type SynchronizerConstructor<R extends "u32" | "u64"> = new (
|
|
20
39
|
properties: SynchronizerComponents<R>,
|