querysub 0.704.0 → 0.706.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.704.0",
3
+ "version": "0.706.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -35,6 +35,7 @@ let DEAD_CHECK_COUNT = 4;
35
35
  // If we find we are unable to write our heartbeat, we have to kill our own process. Otherwise it may
36
36
  // be too out of sync, and might commit unverified data to the disk.
37
37
  let SUICIDE_HEARTBEAT_THRESHOLD = Math.max(timeInMinute * 10, HEARTBEAT_INTERVAL * 4);
38
+ let SELF_HEARTBEAT_CHECK_STARTUP_DELAY = HEARTBEAT_INTERVAL * 5;
38
39
 
39
40
  let CLIENTSIDE_POLL_RATE = timeInMinute * 30;
40
41
 
@@ -492,13 +493,30 @@ async function runMemoryAuditLoop() {
492
493
  runInfinitePoll(API_AUDIT_RATE, fastMemorySync);
493
494
  }
494
495
 
496
+ let firstHeartbeatWriteTime: number | undefined;
497
+
495
498
  async function writeHeartbeat() {
496
499
  if (shutdown) return;
497
- let now = Date.now();
498
500
  let nodeId = getMountNodeId();
499
- console.log(green(`Writing heartbeat ${formatDateTime(now)} for self (${nodeId})`));
500
501
  if (!nodeId) return;
502
+ if (firstHeartbeatWriteTime !== undefined && Date.now() - firstHeartbeatWriteTime >= SELF_HEARTBEAT_CHECK_STARTUP_DELAY && !isNoNetwork()) {
503
+ let lastTime = Number((await archives().get(nodeId))?.toString());
504
+ let suicideThreshold = Date.now() - SUICIDE_HEARTBEAT_THRESHOLD;
505
+ if (!lastTime) {
506
+ console.error(red(`Self node was removed due to heartbeat file not existing (${nodeId}). Terminating self process, as it likely has very stale data.`));
507
+ process.exit();
508
+ }
509
+ if (lastTime < suicideThreshold) {
510
+ console.error(red(`Self node has very old heartbeat. Terminating self process, as it likely has very stale data. ${formatDateTime(lastTime)} < ${formatDateTime(suicideThreshold)}, now is ${formatDateTime(Date.now())}`));
511
+ process.exit();
512
+ }
513
+ }
514
+ let now = Date.now();
515
+ console.log(green(`Writing heartbeat ${formatDateTime(now)} for self (${nodeId})`));
501
516
  await archives().set(nodeId, Buffer.from(now + ""), { fallbacks: true });
517
+ if (firstHeartbeatWriteTime === undefined) {
518
+ firstHeartbeatWriteTime = now;
519
+ }
502
520
  }
503
521
 
504
522
  async function runServerSyncLoops() {
@@ -533,34 +551,15 @@ async function runServerSyncLoops() {
533
551
  console.log(magenta(`Node discovery is loaded`));
534
552
 
535
553
  await runInfinitePollCallAtStart(HEARTBEAT_INTERVAL, writeHeartbeat);
536
- // Delayed by a bit as it might take a little bit for our heartbeat to show up on startup, especially if we are the storage node that is supposed to store our own heartbeat.
537
- delay(HEARTBEAT_INTERVAL * 5).then(() => runInfinitePoll(HEARTBEAT_INTERVAL, async function nodeDiscoverHeartbeat() {
538
- // If we waited too long, other nodes might think we are dead. In which case, we SHOULD terminate.
539
- if (!isNoNetwork()) {
540
- // FIRST, verify we didn't delay too long (to make sure we kill any nodes that were disconnected
541
- // from the internet for too long)
542
- // NOTE: If get can't contact a server, it will throw. It won't return undefined. So if this does return undefined, It means we actually talk to the server and it says the file doesn't exist, which means we are fairly safe in self-terminating.
543
- //let lastTime = Number((await archives().get(selfNodeId, { noFallbacks: true }))?.toString());
544
- // NOTE: We're temporary not using no fallbacks, So, this is a good canary to tell us if something's wrong with storage. We're writing so many heartbeats, at least one of the writes should have gotten to Backblaze.
545
- let lastTime = Number((await archives().get(selfNodeId))?.toString());
546
- let suicideThreshold = Date.now() - SUICIDE_HEARTBEAT_THRESHOLD;
547
- if (!lastTime || lastTime < suicideThreshold) {
548
- if (!lastTime) {
549
- console.error(red(`Self node was removed due to heartbeat file not existing (${selfNodeId}). Terminating self process, as it likely has very stale data.`));
550
- } else {
551
- console.error(red(`Self node was has very old heartbeat. Terminating self process, as it likely has very stale data. ${formatDateTime(lastTime)} < ${formatDateTime(suicideThreshold)}, now is ${formatDateTime(Date.now())}`));
552
- }
553
- process.exit();
554
- }
555
- } else {
556
- // We DO have to re-broadcast, otherwise no one will know we exist
557
- for (let nodeId of allNodeIds2) {
558
- if (isOwnNodeId(nodeId)) continue;
559
- // Ignore errors, as nodes die often, and we only want to log once - when we actually remove the node id.
560
- ignoreErrors(NodeDiscoveryController.nodes[nodeId].addNode(getOwnNodeId()));
561
- }
554
+ runInfinitePoll(HEARTBEAT_INTERVAL, async function nodeDiscoverRebroadcast() {
555
+ if (!isNoNetwork()) return;
556
+ // We DO have to re-broadcast, otherwise no one will know we exist
557
+ for (let nodeId of allNodeIds2) {
558
+ if (isOwnNodeId(nodeId)) continue;
559
+ // Ignore errors, as nodes die often, and we only want to log once - when we actually remove the node id.
560
+ ignoreErrors(NodeDiscoveryController.nodes[nodeId].addNode(getOwnNodeId()));
562
561
  }
563
- }));
562
+ });
564
563
  }
565
564
 
566
565
  let discoveryReady = new PromiseObj<void>();