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 +60 -60
- package/src/-a-archives/archivesBackBlaze.ts +3 -0
- package/src/-g-core-values/NodeCapabilities.ts +6 -4
- package/src/0-path-value-core/NodePathAuthorities.ts +24 -2
- package/src/0-path-value-core/pathValueCore.ts +2221 -2216
- package/src/2-proxy/PathValueProxyWatcher.ts +41 -3
- package/src/3-path-functions/PathFunctionRunner.ts +19 -6
- package/src/3-path-functions/pathFunctionLoader.ts +7 -1
- package/src/4-querysub/QuerysubController.ts +0 -10
- package/src/5-diagnostics/GenericFormat.tsx +3 -1
- package/src/5-diagnostics/TimeGrouper.tsx +2 -0
- package/src/5-diagnostics/nodeMetadata.ts +137 -11
- package/src/diagnostics/NodeViewer.tsx +19 -8
- package/src/diagnostics/logs/DiskLoggerPage.tsx +36 -16
- package/src/diagnostics/logs/diskLogger.ts +12 -1
- package/src/diagnostics/periodic.ts +2 -2
- package/src/diagnostics/trackResources.ts +4 -3
- package/src/diagnostics/watchdog.ts +20 -6
- package/src/library-components/Input.tsx +1 -1
- package/src/zip.ts +1 -0
package/package.json
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
|
56
|
+
let passedNodeIds = new Map<string, string>();
|
|
57
57
|
await Promise.all(nodeIdsToTest.map(async nodeId => {
|
|
58
58
|
if (await doesNodeExposeController(nodeId, controller)) {
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|