querysub 0.43.0 → 0.45.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,60 +1,60 @@
1
- {
2
- "name": "querysub",
3
- "version": "0.43.0",
4
- "main": "index.js",
5
- "license": "MIT",
6
- "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/sliftist/shard.git"
10
- },
11
- "dependencies": {
12
- "@sendgrid/mail": "^7.7.0",
13
- "@types/fs-ext": "^2.0.3",
14
- "@types/node-forge": "^1.3.1",
15
- "@types/pako": "^2.0.3",
16
- "@types/yargs": "^15.0.5",
17
- "acme-client": "^5.0.0",
18
- "cbor-x": "^1.6.0",
19
- "chalk": "^5.2.0",
20
- "diskusage": "^1.2.0",
21
- "fs-ext": "^2.0.0",
22
- "js-sha256": "https://github.com/sliftist/js-sha256",
23
- "js-sha512": "^0.9.0",
24
- "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
25
- "pako": "^2.1.0",
26
- "preact": "^10.11.3",
27
- "socket-function": "^0.39.0",
28
- "terser": "^5.31.0",
29
- "typesafecss": "^0.6.3",
30
- "yaml": "^2.5.0",
31
- "yargs": "^15.3.1"
32
- },
33
- "optionalDependencies": {
34
- "rdtsc-now": "^0.4.2"
35
- },
36
- "scripts": {
37
- "server": "yarn typenode ./src/server.ts",
38
- "serversharded": "yarn server --authority ./pathremain.json & yarn server --authority ./patha.json & yarn server --authority ./pathb.json & yarn server --authority ./pathc.json & yarn server --authority ./pathd.json",
39
- "function": "yarn typenode ./src/3-path-functions/PathFunctionRunnerMain.ts --function --local D:/repos/shard/",
40
- "deploy": "yarn typenode ./src/3-path-functions/deployMain.ts --domain querysub.com --local D:/repos/shard/",
41
- "type": "yarn tsc --noEmit",
42
- "depend": "yarn --silent depcruise src --include-only \"^src\" --config --output-type dot | dot -T svg > dependency-graph.svg",
43
- "dbmerge": "yarn typenode ./src/dbmerge.ts",
44
- "test": "yarn typenode ./src/test/test.tsx --local D:/repos/shard/",
45
- "test2": "yarn typenode ./src/4-dom/qreactTest.tsx --local D:/repos/shard/"
46
- },
47
- "bin": {
48
- "querysub-deploy": "./bin/deploy.js",
49
- "querysub-server": "./bin/server.js",
50
- "querysub-function": "./bin/function.js"
51
- },
52
- "devDependencies": {
53
- "dependency-cruiser": "^12.11.0",
54
- "open": "^8.4.0",
55
- "typedev": "^0.3.0"
56
- },
57
- "resolutions": {
58
- "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6"
59
- }
60
- }
1
+ {
2
+ "name": "querysub",
3
+ "version": "0.45.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/sliftist/shard.git"
10
+ },
11
+ "dependencies": {
12
+ "@sendgrid/mail": "^7.7.0",
13
+ "@types/fs-ext": "^2.0.3",
14
+ "@types/node-forge": "^1.3.1",
15
+ "@types/pako": "^2.0.3",
16
+ "@types/yargs": "^15.0.5",
17
+ "acme-client": "^5.0.0",
18
+ "cbor-x": "^1.6.0",
19
+ "chalk": "^5.2.0",
20
+ "diskusage": "^1.2.0",
21
+ "fs-ext": "^2.0.0",
22
+ "js-sha256": "https://github.com/sliftist/js-sha256",
23
+ "js-sha512": "^0.9.0",
24
+ "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
25
+ "pako": "^2.1.0",
26
+ "preact": "^10.11.3",
27
+ "socket-function": "^0.41.0",
28
+ "terser": "^5.31.0",
29
+ "typesafecss": "^0.6.3",
30
+ "yaml": "^2.5.0",
31
+ "yargs": "^15.3.1"
32
+ },
33
+ "optionalDependencies": {
34
+ "rdtsc-now": "^0.4.2"
35
+ },
36
+ "scripts": {
37
+ "server": "yarn typenode ./src/server.ts",
38
+ "serversharded": "yarn server --authority ./pathremain.json & yarn server --authority ./patha.json & yarn server --authority ./pathb.json & yarn server --authority ./pathc.json & yarn server --authority ./pathd.json",
39
+ "function": "yarn typenode ./src/3-path-functions/PathFunctionRunnerMain.ts --function --local D:/repos/shard/",
40
+ "deploy": "yarn typenode ./src/3-path-functions/deployMain.ts --domain querysub.com --local D:/repos/shard/",
41
+ "type": "yarn tsc --noEmit",
42
+ "depend": "yarn --silent depcruise src --include-only \"^src\" --config --output-type dot | dot -T svg > dependency-graph.svg",
43
+ "dbmerge": "yarn typenode ./src/dbmerge.ts",
44
+ "test": "yarn typenode ./src/test/test.tsx --local D:/repos/shard/",
45
+ "test2": "yarn typenode ./src/4-dom/qreactTest.tsx --local D:/repos/shard/"
46
+ },
47
+ "bin": {
48
+ "querysub-deploy": "./bin/deploy.js",
49
+ "querysub-server": "./bin/server.js",
50
+ "querysub-function": "./bin/function.js"
51
+ },
52
+ "devDependencies": {
53
+ "dependency-cruiser": "^12.11.0",
54
+ "open": "^8.4.0",
55
+ "typedev": "^0.3.0"
56
+ },
57
+ "resolutions": {
58
+ "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6"
59
+ }
60
+ }
@@ -10,6 +10,7 @@ import { devDebugbreak } from "../config";
10
10
  import { formatNumber, formatTime } from "socket-function/src/formatting/format";
11
11
  import { blue, green } from "socket-function/src/formatting/logColors";
12
12
  import debugbreak from "debugbreak";
13
+ import { addTimeProfileDistribution, onTimeProfile } from "../5-diagnostics/nodeMetadata";
13
14
 
14
15
  export function hasBackblazePermissions() {
15
16
  return isNode() && fs.existsSync(getBackblazePath());
@@ -68,11 +69,13 @@ const getAPI = lazy(async () => {
68
69
  }
69
70
  try {
70
71
  let url = auth.apiUrl + "/b2api/v2/" + name;
72
+ let time = Date.now();
71
73
  let result = await httpsRequest(url, Buffer.from(JSON.stringify(arg)), type, undefined, {
72
74
  headers: {
73
75
  Authorization: auth.authorizationToken,
74
76
  }
75
77
  });
78
+ onTimeProfile("Backblaze API", time);
76
79
  return JSON.parse(result.toString());
77
80
  } catch (e: any) {
78
81
  throw new Error(`Error in ${name}, arg ${JSON.stringify(arg).slice(0, 1000)}: ${e.stack}`);
@@ -51,17 +51,19 @@ export async function getControllerNodeId(
51
51
 
52
52
  export async function getControllerNodeIdList(
53
53
  controller: SocketRegistered<{}>,
54
- ): Promise<string[]> {
54
+ ): Promise<{ nodeId: string; entryPoint: string }[]> {
55
55
  let nodeIdsToTest = await getAllNodeIds();
56
- let passedNodeIds = new Set<string>();
56
+ let passedNodeIds = new Map<string, string>();
57
57
  await Promise.all(nodeIdsToTest.map(async nodeId => {
58
58
  if (await doesNodeExposeController(nodeId, controller)) {
59
- passedNodeIds.add(nodeId);
59
+ let entryPoint = await timeoutToUndefinedSilent(10_000, NodeCapabilitiesController.nodes[nodeId].getEntryPoint()) || "Entry point timedout";
60
+ passedNodeIds.set(nodeId, entryPoint);
60
61
  }
61
62
  }));
62
- return Array.from(passedNodeIds);
63
+ return Array.from(passedNodeIds.entries()).map(([nodeId, entryPoint]) => ({ nodeId, entryPoint }));
63
64
  }
64
65
 
66
+
65
67
  export async function doesNodeExposeController(reconnectNodeId: string, controller: SocketRegistered<{}>): Promise<boolean> {
66
68
  let exposedControllers = await timeoutToUndefinedSilent(10_000, NodeCapabilitiesController.nodes[reconnectNodeId].getExposedControllers());
67
69
  return !!exposedControllers?.includes(controller._classGuid);
@@ -31,6 +31,8 @@ const MAX_RECONNECT_TIME = timeInMinute * 15;
31
31
  const RECONNECT_POLL_INTERVAL = 10000;
32
32
 
33
33
  // Poll nodes that appear dead. Without this, if the internet goes down, we might forever ignore nodes.
34
+ const INITIAL_RECOVERY_POLL_INTERVAL = timeInSecond * 5;
35
+ const INITIAL_RECOVERY_RUNS = 100;
34
36
  const RECOVERY_POLL_INTERVAL = timeInMinute;
35
37
 
36
38
  // NOTE: We don't implicitly include parents, as when we add multiple specific paths it is easier
@@ -190,6 +192,8 @@ class NodePathAuthorities {
190
192
  return this.isReadReady;
191
193
  }
192
194
 
195
+ private previouslyNotAvailableNodes = new Set<string>();
196
+
193
197
  @measureFnc
194
198
  private async watchAuthorityPaths() {
195
199
  await onNodeDiscoveryReady();
@@ -237,10 +241,15 @@ class NodePathAuthorities {
237
241
  if (createTime === undefined) {
238
242
  // Don't log for 127-0-0-1, as it usually fails, and is mostly a development optimization
239
243
  if (!nodeId.includes("127-0-0-1")) {
240
- diskLog(`Node didn't respond to getCreateTime`, { nodeId });
244
+ if (!this.previouslyNotAvailableNodes.has(nodeId)) {
245
+ console.log(yellow(`Node didn't respond to getCreateTime`), { nodeId });
246
+ }
241
247
  }
248
+ this.previouslyNotAvailableNodes.add(nodeId);
242
249
  return;
243
250
  }
251
+ this.previouslyNotAvailableNodes.delete(nodeId);
252
+
244
253
  time = Date.now() - time;
245
254
  console.log(blue(`Identifying ${nodeId} as a path authority. ping latency = ${formatTime(time)}`));
246
255
  this.authorities.set(nodeId, {
@@ -294,7 +303,20 @@ class NodePathAuthorities {
294
303
  watchDeltaNodeIds(obj => ingestNewNodeIds(obj.newNodeIds, obj.removedNodeIds));
295
304
  await firstPromise.promise;
296
305
 
297
- runInfinitePoll(RECOVERY_POLL_INTERVAL, async () => {
306
+ let recoveryIndex = 0;
307
+ runInfinitePoll(INITIAL_RECOVERY_POLL_INTERVAL, async () => {
308
+ // Wait longer the more times we loop. This allows us to reconnect quickly on startup
309
+ // (when other nodes might be unavailable or in a weird state), but not waste money
310
+ // hitting backblaze constantly, when we're already in a stable state.
311
+ {
312
+ recoveryIndex++;
313
+ let f = Math.min(1, recoveryIndex / INITIAL_RECOVERY_RUNS);
314
+ let delayTime = (1 - f) * INITIAL_RECOVERY_POLL_INTERVAL + f * RECOVERY_POLL_INTERVAL;
315
+ if (delayTime > INITIAL_RECOVERY_POLL_INTERVAL) {
316
+ await delay(delayTime - INITIAL_RECOVERY_POLL_INTERVAL);
317
+ }
318
+ }
319
+
298
320
  let nodes = await getAllNodeIds();
299
321
  let nonExistentNodes: string[] = [];
300
322
  for (let node of nodes) {