querysub 0.392.0 → 0.393.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.392.0",
3
+ "version": "0.393.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",
@@ -57,7 +57,7 @@
57
57
  "pako": "^2.1.0",
58
58
  "peggy": "^5.0.6",
59
59
  "querysub": "^0.357.0",
60
- "socket-function": "^1.1.4",
60
+ "socket-function": "^1.1.5",
61
61
  "terser": "^5.31.0",
62
62
  "typesafecss": "^0.28.0",
63
63
  "yaml": "^2.5.0",
@@ -17,6 +17,8 @@ setFlag(require, "cbor-x", "allowclient", true);
17
17
 
18
18
  import * as pako from "pako";
19
19
  import { delay } from "socket-function/src/batching";
20
+ import { LZ4 } from "../storage/LZ4";
21
+ import { unblockLoop } from "socket-function/src/batching";
20
22
  setFlag(require, "pako", "allowclient", true);
21
23
 
22
24
  const DEFAULT_BUFFER_SIZE = 1024 * 16;
@@ -32,6 +34,7 @@ const cborEncoder = lazy(() => new cbor.Encoder({ structuredClone: true }));
32
34
 
33
35
  const SERIALIZE_LOCK_COUNT = true;
34
36
 
37
+
35
38
  /*
36
39
  Memory Layout
37
40
  DataSettings
@@ -67,7 +70,7 @@ interface Reader {
67
70
 
68
71
  // JSON.stringify, length prefixed
69
72
  interface DataSettings {
70
- compression?: "gzip";
73
+ compression?: "gzip" | "lz4";
71
74
  valueCount: number;
72
75
  noLocks?: boolean;
73
76
  stripSource?: boolean;
@@ -390,7 +393,7 @@ class PathValueSerializer {
390
393
  let settings: DataSettings = {
391
394
  valueCount: values.length,
392
395
  noLocks: config?.noLocks,
393
- compression: config?.compress ? "gzip" : undefined,
396
+ compression: config?.compress ? "lz4" : undefined,
394
397
  stripSource: config?.stripSource,
395
398
  version,
396
399
  };
@@ -510,7 +513,20 @@ class PathValueSerializer {
510
513
  stringBuffers.reverse();
511
514
  outputBuffers.push(...stringBuffers);
512
515
 
513
- if (settings.compression === "gzip") {
516
+ if (settings.compression === "lz4") {
517
+ let compressedBuffers = await unblockLoop(outputBuffers.slice(1), x => LZ4.compress(x));
518
+ let compressedOutputBuffers = [outputBuffers[0], ...compressedBuffers];
519
+
520
+ // If the compress factor is less than a threshold, use the uncompressed buffers
521
+ let uncompressedSize = outputBuffers.reduce((total, x) => total + x.length, 0);
522
+ let compressedSize = compressedOutputBuffers.reduce((total, x) => total + x.length, 0);
523
+ if (compressedSize / uncompressedSize < MIN_COMPRESS_FACTOR) {
524
+ outputBuffers = compressedOutputBuffers;
525
+ } else {
526
+ settings.compression = undefined;
527
+ outputBuffers[0] = Buffer.from(JSON.stringify(settings));
528
+ }
529
+ } else if (settings.compression === "gzip") {
514
530
  // NOTE: Due to how the LZ77 window works merging buffers probably won't reduce the size by that much.
515
531
  let compressedBuffers = await Promise.all(outputBuffers.slice(1).map(x => Zip.gzip(x, 1)));
516
532
  let compressedOutputBuffers = [outputBuffers[0], ...compressedBuffers];
@@ -574,7 +590,9 @@ class PathValueSerializer {
574
590
 
575
591
  let settings = JSON.parse(buffers.shift()!.toString("utf8")) as DataSettings;
576
592
  let version = settings.version || 0;
577
- if (settings.compression === "gzip") {
593
+ if (settings.compression === "lz4") {
594
+ buffers = await unblockLoop(buffers, x => LZ4.decompress(x));
595
+ } else if (settings.compression === "gzip") {
578
596
  buffers = await Zip.gunzipBatch(buffers);
579
597
  }
580
598
 
@@ -23,6 +23,7 @@ import { getBufferFraction, getBufferInt, getShortNumber } from "../bits";
23
23
  import { devDebugbreak, getDomain, isDevDebugbreak } from "../config";
24
24
  import { waitForFirstTimeSync } from "socket-function/time/trueTimeShim";
25
25
  import { testTCPIsListening } from "socket-function/src/networking";
26
+ import { getMachineId } from "../-a-auth/certs";
26
27
 
27
28
  export const LOCAL_DOMAIN = "LOCAL";
28
29
  export const LOCAL_DOMAIN_PATH = getPathStr1(LOCAL_DOMAIN);
@@ -87,6 +88,8 @@ class NodePathAuthorities {
87
88
 
88
89
  private selfAuthorities: AuthorityPath[] = [];
89
90
 
91
+ private outdatedNodeIds = new Set<string>();
92
+
90
93
  public debug_getAuthority(nodeId: string) {
91
94
  return this.authorities.get(nodeId);
92
95
  }
@@ -251,6 +254,13 @@ class NodePathAuthorities {
251
254
  return;
252
255
  }
253
256
 
257
+ let nodeMachineId = getMachineId(nodeId);
258
+ let onSameMachine = Array.from(this.authorities.keys()).filter(x => getMachineId(x) === nodeMachineId && x !== nodeId);
259
+ if (this.outdatedNodeIds.has(nodeId) && onSameMachine.length > 0) {
260
+ // It's just an old thread that's dead, and once threads die, they don't come back. This should be fairly safe, as we confirm that both a new thread is running on the same port, and that the old thread doesn't respond.
261
+ return;
262
+ }
263
+
254
264
  // Do an initial test by just opening a TCP connection. This will help filter out a lot of dead nodes immediately. Which, in turn, avoids having to create our initial connection signature, which saves a lot of time.
255
265
  if (isNode()) {
256
266
  let nodeIdObj = getNodeIdLocation(nodeId);
@@ -266,6 +276,15 @@ class NodePathAuthorities {
266
276
  let time = Date.now();
267
277
  let createTime = await timeoutToUndefinedSilent(POLL_RATE, PathController.nodes[nodeId].getCreateTime());
268
278
  if (createTime === undefined) {
279
+ if (!isNodeIdLocal(nodeId)) {
280
+ let aliveNodes = await Promise.all(onSameMachine.map(x => errorToUndefinedSilent(PathController.nodes[x].isReadReady())));
281
+ if (aliveNodes.some(x => x)) {
282
+ console.warn(`Node is on the same machine as port as another alive node. AND, it is not responding. Assuming it is just an older version of a dead node`, { nodeId, aliveNodes });
283
+ this.outdatedNodeIds.add(nodeId);
284
+ return;
285
+ }
286
+ }
287
+
269
288
  // Don't log for 127-0-0-1, as it usually fails, and is mostly a development optimization
270
289
  if (!nodeId.includes("127-0-0-1")) {
271
290
  if (!this.previouslyNotAvailableNodes.has(nodeId)) {
@@ -3,7 +3,7 @@ import { nestArchives } from "../../../-a-archives/archives";
3
3
  import { getArchivesBackblaze } from "../../../-a-archives/archivesBackBlaze";
4
4
  import { archiveJSONT } from "../../../-a-archives/archivesJSONT";
5
5
  import { Querysub } from "../../../4-querysub/QuerysubController";
6
- import { getDomain } from "../../../config";
6
+ import { getDomain, isPublic } from "../../../config";
7
7
  import { MachineInfo } from "../../../deployManager/machineSchema";
8
8
  import { createMatchesPattern } from "../IndexedLogs/bufferSearchFindMatcher";
9
9
  import { LogDatum, getErrorLogs } from "../diskLogger";
@@ -482,7 +482,7 @@ const ErrorNotificationServiceBase = SocketFunction.register(
482
482
 
483
483
  class ErrorNotificationData {
484
484
  public async getData() {
485
- let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase);
485
+ let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase, !isPublic());
486
486
  if (!controllerNodeId) {
487
487
  throw new Error(`Could not find node exposing controller ErrorNotificationServiceBase`);
488
488
  }
@@ -490,7 +490,7 @@ class ErrorNotificationData {
490
490
  }
491
491
 
492
492
  public async getUnmatchedErrorsLimited() {
493
- let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase);
493
+ let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase, !isPublic());
494
494
  if (!controllerNodeId) {
495
495
  throw new Error(`Could not find node exposing controller ErrorNotificationServiceBase`);
496
496
  }
@@ -536,7 +536,7 @@ class ErrorNotificationData {
536
536
  }
537
537
 
538
538
  private static ensureWatchingErrorsHTTP = lazy(async () => {
539
- let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase);
539
+ let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase, !isPublic());
540
540
  if (!controllerNodeId) {
541
541
  ErrorNotificationData.ensureWatchingErrorsHTTP.reset();
542
542
  throw new Error(`Could not find node exposing controller ErrorNotificationServiceBase`);
@@ -572,7 +572,7 @@ class ErrorNotificationData {
572
572
  }
573
573
 
574
574
  public async getSuppressionEntries() {
575
- let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase);
575
+ let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase, !isPublic());
576
576
  if (!controllerNodeId) {
577
577
  throw new Error(`Could not find node exposing controller ErrorNotificationServiceBase`);
578
578
  }
@@ -580,7 +580,7 @@ class ErrorNotificationData {
580
580
  }
581
581
 
582
582
  public async setSuppressionEntry(entry: SuppressionEntry) {
583
- let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase);
583
+ let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase, !isPublic());
584
584
  if (!controllerNodeId) {
585
585
  throw new Error(`Could not find node exposing controller ErrorNotificationServiceBase`);
586
586
  }
@@ -588,7 +588,7 @@ class ErrorNotificationData {
588
588
  }
589
589
 
590
590
  public async deleteSuppressionEntry(id: string) {
591
- let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase);
591
+ let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase, !isPublic());
592
592
  if (!controllerNodeId) {
593
593
  throw new Error(`Could not find node exposing controller ErrorNotificationServiceBase`);
594
594
  }
@@ -600,7 +600,7 @@ class ErrorNotificationData {
600
600
  }
601
601
 
602
602
  public async updateSuppressionNotes(id: string, notes: string | undefined) {
603
- let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase);
603
+ let controllerNodeId = await getControllerNodeId(ErrorNotificationServiceBase, !isPublic());
604
604
  if (!controllerNodeId) {
605
605
  throw new Error(`Could not find node exposing controller ErrorNotificationServiceBase`);
606
606
  }
@@ -1,20 +1,14 @@
1
1
  /*
2
2
  todonext
3
3
 
4
+ -1) Deploy everything again!
4
5
 
6
+ -2) Fix synchronization speed from remote to local.
7
+ - I think we just have a lot of data, which our code will detect and log now.
8
+ - And we'll see how much data we are even sending
5
9
 
6
- 2) Publish socket-function and update to use the latest
7
- 1) Deploy everything and make sure the servers run
8
-
10
+ Write Monthly Summary
9
11
 
10
- -1) Change PathValueSerialize to use LZ4
11
- - I think we already have a compression flag here, so it should be easy enough to just change it to support and use LZ4 by default
12
- -3) Send progress/timing when sending very large messages?
13
- - Maybe related to the remote => local synchronization. Maybe we're doing multi- many calls, in which case we can't detect it. But if we're doing just one call... Then the socket function system should realize.
14
- - And even if it's the synchronization code which is doing many calls, then it should probably log progress and timing (on both ends)
15
- -2) Fix synchronization speed from remote to local.
16
- - Last time it seemed very slow
17
- - We might need to jump into the server and look at its profiles there by forcing them to omit, which isn't too hard, but it is kind of annoying.
18
12
  */
19
13
 
20
14
 
package/test.ts CHANGED
@@ -10,31 +10,97 @@ import { SocketFunction } from "socket-function/SocketFunction";
10
10
  import fs from "fs";
11
11
  import { getControllerNodeId, getControllerNodeIdList } from "./src/-g-core-values/NodeCapabilities";
12
12
  import { delay } from "socket-function/src/batching";
13
- import { timeInSecond } from "socket-function/src/misc";
13
+ import { list, timeInSecond } from "socket-function/src/misc";
14
+ import { lazy } from "socket-function/src/caching";
15
+ import { formatNumber } from "socket-function/src/formatting/format";
16
+ import { LZ4 } from "socket-function/src/lz4/LZ4";
17
+
18
+ const paths = [
19
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756166400000-1756252800000.log",
20
+ "D:/repos/qs-cyoa/database-storage/disklogs/cyoa-0-dply-1756252800000-1756339200000.log",
21
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756425600000-1756512000000.log",
22
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756425600000-1756512000000.log",
23
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756684800000-1756771200000.log",
24
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756684800000-1756771200000.log",
25
+ "D:/repos/qs-cyoa/database-storage/disklogs/bootstrapper-0-dply-1756425600000-1756512000000.log",
26
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756598400000-1756684800000.log",
27
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756598400000-1756684800000.log",
28
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756252800000-1756339200000.log",
29
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756252800000-1756339200000.log",
30
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756512000000-1756598400000.log",
31
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756512000000-1756598400000.log",
32
+ "D:/repos/qs-cyoa/database-storage/disklogs/bootstrapper-0-dply-1756339200000-1756425600000.log",
33
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756339200000-1756425600000.log",
34
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756339200000-1756425600000.log",
35
+ "D:/repos/qs-cyoa/database-storage/disklogs/bootstrapper-0-dply-1756684800000-1756771200000.log",
36
+ "D:/repos/qs-cyoa/database-storage/disklogs/function-0-dply-1756425600000-1756512000000.log",
37
+ "D:/repos/qs-cyoa/database-storage/disklogs/bootstrapper-0-dply-1756598400000-1756684800000.log",
38
+ "D:/repos/qs-cyoa/database-storage/disklogs/bootstrapper-0-dply-1756512000000-1756598400000.log",
39
+ "D:/repos/qs-cyoa/database-storage/disklogs/function-0-dply-1756684800000-1756771200000.log",
40
+ "D:/repos/qs-cyoa/database-storage/disklogs/function-0-dply-1756598400000-1756684800000.log",
41
+ "D:/repos/qs-cyoa/database-storage/disklogs/cyoa-0-dply-1756598400000-1756684800000.log",
42
+ "D:/repos/qs-cyoa/database-storage/disklogs/cyoa-1-dply-1756598400000-1756684800000.log",
43
+ "D:/repos/qs-cyoa/database-storage/disklogs/cyoa-0-dply-1756512000000-1756598400000.log",
44
+ "D:/repos/qs-cyoa/database-storage/disklogs/cyoa-1-dply-1756512000000-1756598400000.log",
45
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756166400000-1756252800000.log",
46
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756166400000-1756252800000.log",
47
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756252800000-1756339200000.log",
48
+ "D:/repos/qs-cyoa/database-storage/disklogs/function-0-dply-1756252800000-1756339200000.log",
49
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756425600000-1756512000000.log",
50
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-0-dply-1756080000000-1756166400000.log",
51
+ "D:/repos/qs-cyoa/database-storage/disklogs/gc-0-dply-1756425600000-1756512000000.log",
52
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756339200000-1756425600000.log",
53
+ "D:/repos/qs-cyoa/database-storage/disklogs/gc-0-dply-1756252800000-1756339200000.log",
54
+ "D:/repos/qs-cyoa/database-storage/disklogs/server-1-dply-1756080000000-1756166400000.log",
55
+ "D:/repos/qs-cyoa/database-storage/disklogs/gc-0-dply-1756339200000-1756425600000.log",
56
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756598400000-1756684800000.log",
57
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756684800000-1756771200000.log",
58
+ "D:/repos/qs-cyoa/database-storage/disklogs/cyoa-1-dply-1756252800000-1756339200000.log",
59
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756512000000-1756598400000.log",
60
+ "D:/repos/qs-cyoa/database-storage/disklogs/join-0-dply-1756080000000-1756166400000.log",
61
+ ];
62
+
63
+ const FACTOR = 1;
64
+
65
+
66
+ let getData = lazy(async () => {
67
+ let buffers: Buffer[] = [];
68
+ for (let path of paths) {
69
+ let data = await fs.promises.readFile(path, "utf8");
70
+ buffers.push(Buffer.from(data));
71
+ }
72
+ return list(FACTOR).map(i => buffers.map(b => Buffer.from(b))).flat();
73
+ });
14
74
 
15
- const path = "D:/repos/qs-cyoa/database-storage/disklogs/1757030400000-1757116800000.log";
16
75
  class TestControllerBase {
17
76
  async test() {
18
- return await fs.promises.readFile(path, "utf8");
77
+ return (await getData()).slice();
19
78
  }
20
79
  }
21
80
 
22
81
  const TestController = SocketFunction.register("TestController-019ca5fa-52ef-73bf-b918-4d9cde51b618", new TestControllerBase(), () => ({
23
82
  test: {
24
- compress: true,
83
+ //compress: false
25
84
  },
26
85
  }));
86
+ function compareBuffers(result: Buffer[], correct: Buffer[]) {
87
+ if (result.length !== correct.length) throw new Error(`Result does not match correct: ${result.length} !== ${correct.length}`);
88
+ for (let i = 0; i < result.length; i++) {
89
+ if (!result[i].equals(correct[i])) throw new Error(`Result does not match correct: ${result[i].length} !== ${correct[i].length}, at index ${i}`);
90
+ }
91
+ }
27
92
  async function main() {
28
93
  await Querysub.hostService("testwatcher");
94
+ //SocketFunction.logMessages = true;
29
95
 
30
96
  while (true) {
31
97
  try {
32
98
  let otherNode = await getControllerNodeId(TestController);
33
99
  if (!otherNode) throw new Error("No other node found");
34
- let result = await TestController.nodes[otherNode].test();
35
- let correct = await fs.promises.readFile(path, "utf8");
36
- if (result !== correct) throw new Error("Result does not match correct");
37
- console.log(`Received ${result.length} bytes from ${otherNode}`);
100
+ let result = (await TestController.nodes[otherNode].test());
101
+ let correct = (await getData());
102
+ compareBuffers(result, correct);
103
+ console.log(`Received ${formatNumber(result.reduce((a, b) => a + b.length, 0))} bytes from ${otherNode}`);
38
104
  } catch (e: any) {
39
105
  console.error(e);
40
106
  }