@peerbit/shared-log 7.0.10 → 8.0.0

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/lib/esm/role.d.ts CHANGED
@@ -1,7 +1,4 @@
1
- export declare const containsPoint: (rect: {
2
- offset: number;
3
- factor: number;
4
- }, point: number) => boolean;
1
+ export declare const overlaps: (x1: number, x2: number, y1: number, y2: number) => boolean;
5
2
  export declare abstract class Role {
6
3
  abstract equals(other: Role): any;
7
4
  }
package/lib/esm/role.js CHANGED
@@ -9,23 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  };
10
10
  var NoType_1, Observer_1, Replicator_1;
11
11
  import { field, variant, vec } from "@dao-xyz/borsh";
12
- export const containsPoint = (rect, point) => {
13
- if (rect.factor === 0) {
14
- return false;
15
- }
16
- const start = rect.offset;
17
- const endUnwrapped = rect.offset + rect.factor;
18
- let end = endUnwrapped;
19
- let wrapped = false;
20
- if (endUnwrapped > 1) {
21
- end = endUnwrapped % 1;
22
- wrapped = true;
23
- }
24
- const inFirstInterval = point >= start && point < Math.min(endUnwrapped, 1);
25
- const inSecondInterval = !inFirstInterval && wrapped && point >= 0 && point < end;
26
- return inFirstInterval || inSecondInterval;
27
- };
28
- const overlaps = (x1, x2, y1, y2) => {
12
+ export const overlaps = (x1, x2, y1, y2) => {
29
13
  if (x1 <= y2 && y1 <= x2) {
30
14
  return true;
31
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"role.js","sourceRoot":"","sources":["../../src/role.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"role.js","sourceRoot":"","sources":["../../src/role.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/shared-log",
3
- "version": "7.0.10",
3
+ "version": "8.0.0",
4
4
  "description": "Shared log",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -31,15 +31,15 @@
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
33
  "@dao-xyz/borsh": "^5.2.1",
34
- "@peerbit/log": "3.0.25",
34
+ "@peerbit/log": "3.0.27",
35
35
  "@peerbit/logger": "1.0.2",
36
- "@peerbit/program": "3.0.20",
37
- "@peerbit/rpc": "3.0.24",
36
+ "@peerbit/program": "4.0.0",
37
+ "@peerbit/rpc": "4.0.0",
38
38
  "@peerbit/time": "2.0.6",
39
39
  "p-debounce": "^4.0.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@peerbit/test-utils": "^2.0.24"
42
+ "@peerbit/test-utils": "^2.0.26"
43
43
  },
44
- "gitHead": "2ba4c5e5d682895614713cbef6c779f44508291d"
44
+ "gitHead": "9536898b1f74d42c4f97183b864945fa29422d3e"
45
45
  }
@@ -86,7 +86,7 @@ export class ResponseIPrune extends TransportMessage {
86
86
  }
87
87
  }
88
88
 
89
- const MAX_EXCHANGE_MESSAGE_SIZE = 5e6; // 5mb (since stream limits are 10mb)
89
+ const MAX_EXCHANGE_MESSAGE_SIZE = 1e5; // 100kb. Too large size might not be faster (even if we can do 5mb)
90
90
 
91
91
  export const createExchangeHeadsMessages = async (
92
92
  log: Log<any>,
package/src/index.ts CHANGED
@@ -51,7 +51,6 @@ import yallist from "yallist";
51
51
  import {
52
52
  AcknowledgeDelivery,
53
53
  DeliveryMode,
54
- SeekDelivery,
55
54
  SilentDelivery,
56
55
  NotStartedError
57
56
  } from "@peerbit/stream-interface";
@@ -62,7 +61,7 @@ import { PIDReplicationController } from "./pid.js";
62
61
  export * from "./replication.js";
63
62
  import PQueue from "p-queue";
64
63
  import { CPUUsage, CPUUsageIntervalLag } from "./cpu.js";
65
- import { collectNodesAroundPoint, getCover } from "./ranges.js";
64
+ import { getCoverSet, getSamples, isMatured } from "./ranges.js";
66
65
  export { type CPUUsage, CPUUsageIntervalLag };
67
66
  export { Observer, Replicator, Role };
68
67
 
@@ -92,20 +91,20 @@ export type ReplicationLimitsOptions =
92
91
 
93
92
  type StringRoleOptions = "observer" | "replicator";
94
93
 
95
- type AdaptiveReplicatorOptions = {
94
+ export type AdaptiveReplicatorOptions = {
96
95
  type: "replicator";
97
96
  limits?: {
98
- memory?: number;
97
+ storage?: number;
99
98
  cpu?: number | { max: number; monitor?: CPUUsage };
100
99
  };
101
100
  };
102
101
 
103
- type FixedReplicatorOptions = {
102
+ export type FixedReplicatorOptions = {
104
103
  type: "replicator";
105
104
  factor: number;
106
105
  };
107
106
 
108
- type ObserverType = {
107
+ export type ObserverType = {
109
108
  type: "observer";
110
109
  };
111
110
 
@@ -167,7 +166,7 @@ export class SharedLog<T = Uint8Array> extends Program<
167
166
 
168
167
  // options
169
168
  private _role: Observer | Replicator;
170
- private _roleOptions: AdaptiveReplicatorOptions | Observer | Replicator;
169
+ private _roleConfig: AdaptiveReplicatorOptions | Observer | Replicator;
171
170
  private _sortedPeersCache: yallist<ReplicatorRect> | undefined;
172
171
  private _totalParticipation: number;
173
172
  private _gidPeersHistory: Map<string, Set<string>>;
@@ -204,6 +203,7 @@ export class SharedLog<T = Uint8Array> extends Program<
204
203
  private remoteBlocks: RemoteBlocks;
205
204
 
206
205
  private openTime: number;
206
+ private oldestOpenTime: number;
207
207
 
208
208
  private sync?: (entry: Entry<T>) => boolean;
209
209
 
@@ -219,6 +219,7 @@ export class SharedLog<T = Uint8Array> extends Program<
219
219
  private syncMoreInterval?: ReturnType<typeof setTimeout>;
220
220
  private syncInFlightQueue: Map<string, PublicSignKey[]>;
221
221
  private syncInFlightQueueInverted: Map<string, Set<string>>;
222
+ private syncInFlight: Map<string, Map<string, { timestamp: number }>>;
222
223
 
223
224
  replicas: ReplicationLimits;
224
225
 
@@ -233,10 +234,20 @@ export class SharedLog<T = Uint8Array> extends Program<
233
234
  this.rpc = new RPC();
234
235
  }
235
236
 
237
+ /**
238
+ * Returns the current role
239
+ */
236
240
  get role(): Observer | Replicator {
237
241
  return this._role;
238
242
  }
239
243
 
244
+ /**
245
+ * Return the
246
+ */
247
+ get roleConfig(): Observer | Replicator | AdaptiveReplicatorOptions {
248
+ return this._roleConfig;
249
+ }
250
+
240
251
  get totalParticipation(): number {
241
252
  return this._totalParticipation;
242
253
  }
@@ -261,9 +272,9 @@ export class SharedLog<T = Uint8Array> extends Program<
261
272
  this.replicationController = new PIDReplicationController(
262
273
  this.node.identity.publicKey.hashcode(),
263
274
  {
264
- memory:
265
- options?.limits?.memory != null
266
- ? { max: options?.limits?.memory }
275
+ storage:
276
+ options?.limits?.storage != null
277
+ ? { max: options?.limits?.storage }
267
278
  : undefined,
268
279
  cpu:
269
280
  options?.limits?.cpu != null
@@ -289,49 +300,49 @@ export class SharedLog<T = Uint8Array> extends Program<
289
300
  if (options instanceof Observer || options instanceof Replicator) {
290
301
  throw new Error("Unsupported role option type");
291
302
  } else if (options === "observer") {
292
- this._roleOptions = new Observer();
303
+ this._roleConfig = new Observer();
293
304
  } else if (options === "replicator") {
294
305
  setupDebouncedRebalancing();
295
- this._roleOptions = { type: options };
306
+ this._roleConfig = { type: options };
296
307
  } else if (options) {
297
308
  if (options.type === "replicator") {
298
309
  if (isAdaptiveReplicatorOption(options)) {
299
310
  setupDebouncedRebalancing(options);
300
- this._roleOptions = options;
311
+ this._roleConfig = options;
301
312
  } else {
302
- this._roleOptions = new Replicator({
313
+ this._roleConfig = new Replicator({
303
314
  factor: options.factor,
304
- offset: hashToUniformNumber(this.node.identity.publicKey.bytes)
315
+ offset: this.getReplicationOffset()
305
316
  });
306
317
  }
307
318
  } else {
308
- this._roleOptions = new Observer();
319
+ this._roleConfig = new Observer();
309
320
  }
310
321
  } else {
311
322
  // Default option
312
323
  setupDebouncedRebalancing();
313
- this._roleOptions = { type: "replicator" };
324
+ this._roleConfig = { type: "replicator" };
314
325
  }
315
326
 
316
327
  // setup the initial role
317
328
 
318
329
  if (
319
- this._roleOptions instanceof Replicator ||
320
- this._roleOptions instanceof Observer
330
+ this._roleConfig instanceof Replicator ||
331
+ this._roleConfig instanceof Observer
321
332
  ) {
322
- this._role = this._roleOptions as Replicator | Observer;
333
+ this._role = this._roleConfig as Replicator | Observer;
323
334
  } else {
324
335
  // initial role in a dynamic setup
325
336
 
326
- if (this._roleOptions?.limits) {
337
+ if (this._roleConfig?.limits) {
327
338
  this._role = new Replicator({
328
339
  factor: this._role instanceof Replicator ? this._role.factor : 0,
329
- offset: hashToUniformNumber(this.node.identity.publicKey.bytes)
340
+ offset: this.getReplicationOffset()
330
341
  });
331
342
  } else {
332
343
  this._role = new Replicator({
333
344
  factor: this._role instanceof Replicator ? this._role.factor : 1,
334
- offset: hashToUniformNumber(this.node.identity.publicKey.bytes)
345
+ offset: this.getReplicationOffset()
335
346
  });
336
347
  }
337
348
  }
@@ -354,12 +365,7 @@ export class SharedLog<T = Uint8Array> extends Program<
354
365
  );
355
366
 
356
367
  await this.rpc.subscribe();
357
-
358
- await this.rpc.send(new ResponseRoleMessage({ role: this._role }), {
359
- mode: new SeekDelivery({
360
- redundancy: 1
361
- })
362
- });
368
+ await this.rpc.send(new ResponseRoleMessage({ role: this._role }));
363
369
 
364
370
  if (onRoleChange && changed !== "none") {
365
371
  this.onRoleChange(this._role, this.node.identity.publicKey);
@@ -418,6 +424,15 @@ export class SharedLog<T = Uint8Array> extends Program<
418
424
  }
419
425
  leaders = newAndOldLeaders;
420
426
  }
427
+ let set = this._gidPeersHistory.get(result.entry.meta.gid);
428
+ if (!set) {
429
+ set = new Set(leaders);
430
+ this._gidPeersHistory.set(result.entry.meta.gid, set);
431
+ } else {
432
+ for (const receiver of leaders) {
433
+ set.add(receiver);
434
+ }
435
+ }
421
436
  mode = isLeader
422
437
  ? new SilentDelivery({ redundancy: 1, to: leaders })
423
438
  : new AcknowledgeDelivery({ redundancy: 1, to: leaders });
@@ -453,7 +468,9 @@ export class SharedLog<T = Uint8Array> extends Program<
453
468
  this.latestRoleMessages = new Map();
454
469
  this.syncInFlightQueue = new Map();
455
470
  this.syncInFlightQueueInverted = new Map();
471
+ this.syncInFlight = new Map();
456
472
  this.openTime = +new Date();
473
+ this.oldestOpenTime = this.openTime;
457
474
  this.timeUntilRoleMaturity =
458
475
  options?.timeUntilRoleMaturity || WAIT_FOR_ROLE_MATURITY;
459
476
  this.waitForReplicatorTimeout =
@@ -467,7 +484,7 @@ export class SharedLog<T = Uint8Array> extends Program<
467
484
  this.setupRole(options?.role);
468
485
 
469
486
  const id = sha256Base64Sync(this.log.id);
470
- const storage = await this.node.memory.sublevel(id);
487
+ const storage = await this.node.storage.sublevel(id);
471
488
 
472
489
  const localBlocks = await new AnyBlockStore(
473
490
  await storage.sublevel("blocks")
@@ -590,21 +607,25 @@ export class SharedLog<T = Uint8Array> extends Program<
590
607
  this.syncInFlightQueue.delete(key);
591
608
  }
592
609
  }
593
- this.rpc
594
- .send(
595
- new ResponseMaybeSync({
596
- hashes: requestHashes
597
- }),
598
- {
599
- mode: new SilentDelivery({ to: from, redundancy: 1 })
600
- }
601
- )
602
- .finally(() => {
603
- if (this.closed) {
604
- return;
610
+
611
+ const nowMin10s = +new Date() - 1e4;
612
+ for (const [key, map] of this.syncInFlight) {
613
+ // cleanup "old" missing syncs
614
+ for (const [hash, { timestamp }] of map) {
615
+ if (timestamp < nowMin10s) {
616
+ map.delete(hash);
605
617
  }
606
- this.syncMoreInterval = setTimeout(requestSync, 1e4);
607
- });
618
+ }
619
+ if (map.size === 0) {
620
+ this.syncInFlight.delete(key);
621
+ }
622
+ }
623
+ this.requestSync(requestHashes, from).finally(() => {
624
+ if (this.closed) {
625
+ return;
626
+ }
627
+ this.syncMoreInterval = setTimeout(requestSync, 1e4);
628
+ });
608
629
  };
609
630
  requestSync();
610
631
  }
@@ -668,6 +689,7 @@ export class SharedLog<T = Uint8Array> extends Program<
668
689
  this._pendingIHave.clear();
669
690
  this.syncInFlightQueue.clear();
670
691
  this.syncInFlightQueueInverted.clear();
692
+ this.syncInFlight.clear();
671
693
  this.latestRoleMessages.clear();
672
694
  this._gidPeersHistory.clear();
673
695
 
@@ -824,6 +846,17 @@ export class SharedLog<T = Uint8Array> extends Program<
824
846
  this.rebalanceParticipationDebounced?.();
825
847
  }
826
848
 
849
+ /// we clear sync in flight here because we want to join before that, so that entries are totally accounted for
850
+ for (const head of heads) {
851
+ const set = this.syncInFlight.get(context.from.hashcode());
852
+ if (set) {
853
+ set.delete(head.entry.hash);
854
+ if (set?.size === 0) {
855
+ this.syncInFlight.delete(context.from.hashcode());
856
+ }
857
+ }
858
+ }
859
+
827
860
  if (maybeDelete) {
828
861
  for (const entries of maybeDelete as EntryWithRefs<any>[][]) {
829
862
  const headsWithGid = this.log.headsIndex.gids.get(
@@ -930,18 +963,11 @@ export class SharedLog<T = Uint8Array> extends Program<
930
963
  inverted.add(hash);
931
964
  } else if (!this.log.has(hash)) {
932
965
  this.syncInFlightQueue.set(hash, []);
933
- requestHashes.push(hash);
966
+ requestHashes.push(hash); // request immediately (first time we have seen this hash)
934
967
  }
935
968
  }
936
969
 
937
- await this.rpc.send(
938
- new ResponseMaybeSync({
939
- hashes: requestHashes
940
- }),
941
- {
942
- mode: new SilentDelivery({ to: [context.from], redundancy: 1 })
943
- }
944
- );
970
+ await this.requestSync(requestHashes, [context.from.hashcode()]);
945
971
  } else if (msg instanceof ResponseMaybeSync) {
946
972
  // TODO better choice of step size
947
973
  const entries = (
@@ -1042,10 +1068,12 @@ export class SharedLog<T = Uint8Array> extends Program<
1042
1068
  async waitForReplicator(...keys: PublicSignKey[]) {
1043
1069
  const check = () => {
1044
1070
  for (const k of keys) {
1071
+ const rect = this.getReplicatorsSorted()
1072
+ ?.toArray()
1073
+ ?.find((x) => x.publicKey.equals(k));
1045
1074
  if (
1046
- !this.getReplicatorsSorted()
1047
- ?.toArray()
1048
- ?.find((x) => x.publicKey.equals(k))
1075
+ !rect ||
1076
+ !isMatured(rect.role, +new Date(), this.getDefaultMinRoleAge())
1049
1077
  ) {
1050
1078
  return false;
1051
1079
  }
@@ -1069,6 +1097,10 @@ export class SharedLog<T = Uint8Array> extends Program<
1069
1097
  return !!isLeader;
1070
1098
  }
1071
1099
 
1100
+ private getReplicationOffset() {
1101
+ return hashToUniformNumber(this.node.identity.publicKey.bytes);
1102
+ }
1103
+
1072
1104
  private async waitForIsLeader(
1073
1105
  slot: { toString(): string },
1074
1106
  numberOfLeaders: number,
@@ -1137,6 +1169,17 @@ export class SharedLog<T = Uint8Array> extends Program<
1137
1169
  return this.findLeadersFromUniformNumber(cursor, numberOfLeaders, options);
1138
1170
  }
1139
1171
 
1172
+ getDefaultMinRoleAge(): number {
1173
+ const now = +new Date();
1174
+ const replLength = this.getReplicatorsSorted()!.length;
1175
+ const diffToOldest =
1176
+ replLength > 1 ? now - this.oldestOpenTime - 1 : Number.MAX_SAFE_INTEGER;
1177
+ return Math.min(
1178
+ this.timeUntilRoleMaturity,
1179
+ diffToOldest,
1180
+ (this.timeUntilRoleMaturity * Math.log(replLength)) / 3
1181
+ ); // / 3 so that if 2 replicators and timeUntilRoleMaturity = 1e4 the result will be 1
1182
+ }
1140
1183
  private findLeadersFromUniformNumber(
1141
1184
  cursor: number,
1142
1185
  numberOfLeaders: number,
@@ -1144,33 +1187,26 @@ export class SharedLog<T = Uint8Array> extends Program<
1144
1187
  roleAge?: number;
1145
1188
  }
1146
1189
  ) {
1147
- const leaders: Set<string> = new Set();
1148
- const width = 1;
1149
- const peers = this.getReplicatorsSorted();
1150
- if (!peers || peers?.length === 0) {
1151
- return [];
1152
- }
1153
- numberOfLeaders = Math.min(numberOfLeaders, peers.length);
1190
+ const roleAge = options?.roleAge ?? this.getDefaultMinRoleAge(); // TODO -500 as is added so that i f someone else is just as new as us, then we treat them as mature as us. without -500 we might be slower syncing if two nodes starts almost at the same time
1154
1191
 
1155
- const t = +new Date();
1156
- const roleAge =
1157
- options?.roleAge ??
1158
- Math.min(this.timeUntilRoleMaturity, +new Date() - this.openTime - 500); // TODO -500 as is added so that i f someone else is just as new as us, then we treat them as mature as us. without -500 we might be slower syncing if two nodes starts almost at the same time
1159
-
1160
- for (let i = 0; i < numberOfLeaders; i++) {
1161
- const point = ((cursor + i / numberOfLeaders) % 1) * width;
1162
- const currentNode = peers.head;
1163
- collectNodesAroundPoint(t, roleAge, peers, currentNode, leaders, point);
1164
- }
1192
+ const sampes = getSamples(
1193
+ cursor,
1194
+ this.getReplicatorsSorted()!,
1195
+ numberOfLeaders,
1196
+ roleAge,
1197
+ this.role instanceof Replicator && this.role.factor === 0
1198
+ ? this.node.identity.publicKey.hashcode()
1199
+ : undefined
1200
+ );
1165
1201
 
1166
- return [...leaders];
1202
+ return sampes;
1167
1203
  }
1168
1204
 
1169
1205
  /**
1170
1206
  *
1171
1207
  * @returns groups where at least one in any group will have the entry you are looking for
1172
1208
  */
1173
- getReplicatorUnion(roleAge: number = this.timeUntilRoleMaturity) {
1209
+ getReplicatorUnion(roleAge: number = this.getDefaultMinRoleAge()) {
1174
1210
  if (this.closed === true) {
1175
1211
  throw new Error("Closed");
1176
1212
  }
@@ -1192,12 +1228,18 @@ export class SharedLog<T = Uint8Array> extends Program<
1192
1228
  // the entry we are looking for
1193
1229
  const coveringWidth = width / minReplicas;
1194
1230
 
1195
- return getCover(
1231
+ const set = getCoverSet(
1196
1232
  coveringWidth,
1197
1233
  peers,
1198
1234
  roleAge,
1199
1235
  this.role instanceof Replicator ? this.node.identity.publicKey : undefined
1200
1236
  );
1237
+
1238
+ // add all in flight
1239
+ for (const [key, _] of this.syncInFlight) {
1240
+ set.add(key);
1241
+ }
1242
+ return [...set];
1201
1243
  }
1202
1244
 
1203
1245
  async replicator(
@@ -1255,7 +1297,7 @@ export class SharedLog<T = Uint8Array> extends Program<
1255
1297
  await this.rebalanceParticipationDebounced?.(); /* await this.rebalanceParticipation(false); */
1256
1298
  if (update.changed === "added") {
1257
1299
  await this.rpc.send(new ResponseRoleMessage({ role: this._role }), {
1258
- mode: new SeekDelivery({
1300
+ mode: new SilentDelivery({
1259
1301
  to: [publicKey.hashcode()],
1260
1302
  redundancy: 1
1261
1303
  })
@@ -1303,6 +1345,10 @@ export class SharedLog<T = Uint8Array> extends Program<
1303
1345
  // TODO should we remove replicators if they are already added?
1304
1346
  return { changed: "none" };
1305
1347
  }
1348
+ this.oldestOpenTime = Math.min(
1349
+ this.oldestOpenTime,
1350
+ Number(role.timestamp)
1351
+ );
1306
1352
 
1307
1353
  // insert or if already there do nothing
1308
1354
  const rect: ReplicatorRect = {
@@ -1380,13 +1426,29 @@ export class SharedLog<T = Uint8Array> extends Program<
1380
1426
  for (const [_a, b] of this._gidPeersHistory) {
1381
1427
  b.delete(publicKey.hashcode());
1382
1428
  }
1429
+ this.syncInFlight.delete(publicKey.hashcode());
1430
+ const waitingHashes = this.syncInFlightQueueInverted.get(
1431
+ publicKey.hashcode()
1432
+ );
1433
+ if (waitingHashes) {
1434
+ for (const hash of waitingHashes) {
1435
+ let arr = this.syncInFlightQueue.get(hash);
1436
+ if (arr) {
1437
+ arr = arr.filter((x) => !x.equals(publicKey));
1438
+ }
1439
+ if (this.syncInFlightQueue.size === 0) {
1440
+ this.syncInFlightQueue.delete(hash);
1441
+ }
1442
+ }
1443
+ }
1444
+ this.syncInFlightQueueInverted.delete(publicKey.hashcode());
1383
1445
  }
1384
1446
 
1385
1447
  if (subscribed) {
1386
1448
  if (this.role instanceof Replicator) {
1387
1449
  this.rpc
1388
1450
  .send(new ResponseRoleMessage({ role: this._role }), {
1389
- mode: new SeekDelivery({ redundancy: 1, to: [publicKey] })
1451
+ mode: new SilentDelivery({ redundancy: 1, to: [publicKey] })
1390
1452
  })
1391
1453
  .catch((e) => logger.error(e.toString()));
1392
1454
  }
@@ -1637,6 +1699,29 @@ export class SharedLog<T = Uint8Array> extends Program<
1637
1699
  return changed;
1638
1700
  }
1639
1701
 
1702
+ private async requestSync(hashes: string[], to: Set<string> | string[]) {
1703
+ const now = +new Date();
1704
+ for (const node of to) {
1705
+ let map = this.syncInFlight.get(node);
1706
+ if (!map) {
1707
+ map = new Map();
1708
+ this.syncInFlight.set(node, map);
1709
+ }
1710
+ for (const hash of hashes) {
1711
+ map.set(hash, { timestamp: now });
1712
+ }
1713
+ }
1714
+
1715
+ await this.rpc.send(
1716
+ new ResponseMaybeSync({
1717
+ hashes: hashes
1718
+ }),
1719
+ {
1720
+ mode: new SilentDelivery({ to, redundancy: 1 })
1721
+ }
1722
+ );
1723
+ }
1724
+
1640
1725
  async _onUnsubscription(evt: CustomEvent<UnsubcriptionEvent>) {
1641
1726
  logger.debug(
1642
1727
  `Peer disconnected '${evt.detail.from.hashcode()}' from '${JSON.stringify(
@@ -1715,13 +1800,13 @@ export class SharedLog<T = Uint8Array> extends Program<
1715
1800
  }
1716
1801
 
1717
1802
  // The role is fixed (no changes depending on memory usage or peer count etc)
1718
- if (this._roleOptions instanceof Role) {
1803
+ if (this._roleConfig instanceof Role) {
1719
1804
  return false;
1720
1805
  }
1721
1806
 
1722
1807
  // TODO second condition: what if the current role is Observer?
1723
1808
  if (
1724
- this._roleOptions.type == "replicator" &&
1809
+ this._roleConfig.type == "replicator" &&
1725
1810
  this._role instanceof Replicator
1726
1811
  ) {
1727
1812
  const peers = this.getReplicatorsSorted();
package/src/pid.ts CHANGED
@@ -1,10 +1,3 @@
1
- type ReplicationErrorFunction = (objectives: {
2
- coverage: number;
3
- balance: number;
4
- memory: number;
5
- cpu: number;
6
- }) => number;
7
-
8
1
  export class PIDReplicationController {
9
2
  integral: number;
10
3
  prevError: number;
@@ -18,14 +11,14 @@ export class PIDReplicationController {
18
11
  constructor(
19
12
  readonly id: string,
20
13
  options: {
21
- memory?: { max: number };
14
+ storage?: { max: number };
22
15
  cpu?: { max: number };
23
16
  kp?: number;
24
17
  ki?: number;
25
18
  kd?: number;
26
19
  } = {}
27
20
  ) {
28
- const { memory, cpu, kp = 0.7, ki = 0.025, kd = 0.05 } = options;
21
+ const { storage: memory, cpu, kp = 0.7, ki = 0.025, kd = 0.05 } = options;
29
22
  this.kp = kp;
30
23
  this.ki = ki;
31
24
  this.kd = kd;