querysub 0.128.0 → 0.130.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.128.0",
3
+ "version": "0.130.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",
@@ -144,7 +144,7 @@ export async function deployMain() {
144
144
  },
145
145
  });
146
146
 
147
- console.log(magenta(`FINISHED DEPLOY`));
147
+ console.log(magenta(`FINISHED DEPLOY (${gitRef})`));
148
148
  }
149
149
 
150
150
 
@@ -303,6 +303,17 @@ async function edgeNodeFunction(config: {
303
303
 
304
304
  // I guess... only allow private nodes, if they specify the exact host (which would match above).
305
305
  edgeNodes = edgeNodes.filter(x => x.public);
306
+ if (edgeNodes.length === 0) {
307
+ throw new Error(`No public nodes found`);
308
+ }
309
+
310
+ let liveNodes = edgeNodes.filter(x => x.gitHash === edgeIndex.liveHash);
311
+ if (liveNodes.length === 0) {
312
+ let latestHash = edgeNodes[0].gitHash;
313
+ console.warn(`Could not find any live nodes (${edgeIndex.liveHash}), falling back to latest hash: ${latestHash}`);
314
+ liveNodes = edgeNodes.filter(x => x.gitHash === latestHash);
315
+ }
316
+ edgeNodes = liveNodes;
306
317
 
307
318
  // TODO: Instead of randomly shuffling, use the node's current load when picking a node.
308
319
  // All our future traffic (such as syncing) goes through the edge node we use, so it preferrable
@@ -18,7 +18,7 @@ import path from "path";
18
18
  import debugbreak from "debugbreak";
19
19
  import { requiresNetworkTrustHook } from "../-d-trust/NetworkTrust2";
20
20
  import { getControllerNodeIdList } from "../-g-core-values/NodeCapabilities";
21
- import { blue } from "socket-function/src/formatting/logColors";
21
+ import { blue, magenta } from "socket-function/src/formatting/logColors";
22
22
  import { errorToUndefined } from "../errors";
23
23
  import { deploySchema } from "./deploySchema";
24
24
  import { proxyWatcher } from "../2-proxy/PathValueProxyWatcher";
@@ -29,6 +29,7 @@ const UPDATE_POLL_INTERVAL = timeInMinute;
29
29
  const DEAD_NODE_COUNT_THRESHOLD = 15;
30
30
 
31
31
  const edgeNodeStorage = nestArchives("edgenodes/", getArchivesBackblazePublic(getDomain()));
32
+ const edgeNodeIndexFile = "edge-nodes-index.json";
32
33
 
33
34
  const getEdgeNodeConfig = cacheLimited(10000, async (fileName: string): Promise<EdgeNodeConfig | undefined> => {
34
35
  let edgeNodeConfig = await edgeNodeStorage.get(fileName);
@@ -48,15 +49,20 @@ function getNodeIdFromPath(path: string) {
48
49
  // NOTE: We update this in the update loop
49
50
  const getEdgeNodesIndex = lazy(async (): Promise<EdgeNodesIndex> => {
50
51
  await startUpdateLoop();
51
- let edgeNodesIndex = await edgeNodeStorage.get("edgeNodesIndex.json");
52
+ let edgeNodesIndex = await edgeNodeStorage.get(edgeNodeIndexFile);
53
+ let liveHash = await Querysub.commitSynced(() => {
54
+ return deploySchema()[getDomain()].deploy.live.hash;
55
+ });
52
56
  if (!edgeNodesIndex) return {
53
57
  edgeNodes: [],
58
+ liveHash,
54
59
  };
55
60
  return JSON.parse(edgeNodesIndex.toString());
56
61
  });
57
62
 
58
63
  export type EdgeNodesIndex = {
59
64
  edgeNodes: EdgeNodeConfig[];
65
+ liveHash: string;
60
66
  };
61
67
 
62
68
 
@@ -91,21 +97,12 @@ export async function registerEdgeNode(config: {
91
97
 
92
98
  await waitForFirstTimeSync();
93
99
 
94
- let gitHash = getGitRef();
95
-
96
100
  if (!isLocal()) {
97
- gitHash = await Querysub.commitSynced(() => {
98
- return deploySchema()[getDomain()].deploy.live.hash;
99
- });
100
101
  let loadedHash = "";
101
102
  Querysub.createWatcher(() => {
102
103
  let hash = deploySchema()[getDomain()].deploy.live.hash;
103
104
  if (hash === loadedHash || !Querysub.isAllSynced()) return;
104
105
 
105
- // todonext
106
- // Remove this line, it is just to verify our preloading works
107
- if (loadedHash) return;
108
-
109
106
  loadedHash = hash;
110
107
  void Promise.resolve().then(async () => {
111
108
  await loadEntryPointsByHash({
@@ -116,6 +113,7 @@ export async function registerEdgeNode(config: {
116
113
  });
117
114
  });
118
115
  } else {
116
+ let gitHash = getGitRef();
119
117
 
120
118
  let nodeId = getOwnNodeId();
121
119
  let machineId = getOwnMachineId();
@@ -177,9 +175,12 @@ const loadEntryPointsByHash = runInSerial(async function loadEntryPointsByHash(c
177
175
  };
178
176
 
179
177
  await edgeNodeStorage.set(getNextNodePath(), Buffer.from(JSON.stringify(edgeNodeConfig)));
178
+ console.log(magenta(`Deployed edge node`), edgeNodeConfig);
180
179
 
181
180
  SocketFunction.expose(EdgeNodeController);
182
181
 
182
+ await updateEdgeNodesFile();
183
+
183
184
  onEdgeNodesChanged();
184
185
  });
185
186
 
@@ -189,7 +190,7 @@ export const getEdgeNodeConfigURL = lazy(async () => {
189
190
  subdomain: `edge`,
190
191
  domain: getDomain(),
191
192
  });
192
- return await getURL("edge-nodes-index.json");
193
+ return await getURL(edgeNodeIndexFile);
193
194
  });
194
195
 
195
196
  const startUpdateLoop = lazy(async () => {
@@ -220,34 +221,43 @@ async function runEdgeNodesAliveCheck() {
220
221
  }
221
222
  }
222
223
  async function updateEdgeNodesFile() {
223
- let prevEdgeNodeFile = await edgeNodeStorage.get("edgeNodesIndex.json");
224
+ let prevEdgeNodeFile = await edgeNodeStorage.get(edgeNodeIndexFile);
224
225
  let prevEdgeNodeIndex: EdgeNodesIndex = {
225
226
  edgeNodes: [],
227
+ liveHash: "",
226
228
  };
227
229
  try {
228
230
  if (prevEdgeNodeFile) {
229
231
  prevEdgeNodeIndex = JSON.parse(prevEdgeNodeFile.toString());
230
232
  }
231
233
  } catch (e) {
232
- console.error("Failed to parse edgeNodesIndex.json", { error: e, prevEdgeNodeFile });
234
+ console.error(`Failed to parse ${edgeNodeIndexFile}`, { error: e, prevEdgeNodeFile });
233
235
  }
236
+
234
237
  getEdgeNodesIndex.set(Promise.resolve(prevEdgeNodeIndex));
235
238
 
236
239
  let edgeNodeFiles = await edgeNodeStorage.find("node", { type: "files" });
237
240
  let edgeNodeNodeIds = edgeNodeFiles.map(getNodeIdFromPath);
238
241
 
239
- if (!edgeNodeNodeIds.includes(getOwnNodeId())) {
240
- console.log(`Our node was removed as a edgeNode. This is a fatal error. Terminating now.`);
241
- await shutdown();
242
- }
242
+ let liveHash = await Querysub.commitSynced(() => {
243
+ return deploySchema()[getDomain()].deploy.live.hash;
244
+ });
243
245
 
244
246
  let diff = !!compareArray(edgeNodeNodeIds.sort(), prevEdgeNodeIndex.edgeNodes.map(x => x.nodeId).sort());
247
+ if (diff) {
248
+ console.log(`Detected edgeNodes changed. Updating ${edgeNodeIndexFile}`, { edgeNodeNodeIds, liveHash });
249
+ }
250
+ if (liveHash !== prevEdgeNodeIndex.liveHash) {
251
+ diff = true;
252
+ console.log(`Detected live hash changed. Updating ${edgeNodeIndexFile}`, { liveHash, prevHash: prevEdgeNodeIndex.liveHash });
253
+ }
245
254
  if (!diff) return;
246
255
 
247
- console.log("Detected edgeNodes changed. Updating edgeNodesIndex.json", { edgeNodeNodeIds });
256
+
248
257
 
249
258
  let newEdgeNodeIndex: EdgeNodesIndex = {
250
259
  edgeNodes: [],
260
+ liveHash,
251
261
  };
252
262
  for (let nodeFile of edgeNodeFiles) {
253
263
  let edgeNodeConfig = await getEdgeNodeConfig(nodeFile);
@@ -255,7 +265,7 @@ async function updateEdgeNodesFile() {
255
265
  newEdgeNodeIndex.edgeNodes.push(edgeNodeConfig);
256
266
  }
257
267
 
258
- await edgeNodeStorage.set("edge-nodes-index.json", Buffer.from(JSON.stringify(newEdgeNodeIndex)));
268
+ await edgeNodeStorage.set(edgeNodeIndexFile, Buffer.from(JSON.stringify(newEdgeNodeIndex)));
259
269
  }
260
270
 
261
271
  export async function preloadUI(hash: string) {
@@ -315,16 +325,6 @@ const EdgeNodeController = SocketFunction.register(
315
325
  // - I think it isn't? But maybe we just need to do-update again
316
326
 
317
327
 
318
- // 3) Dynamically watch the live hash, and load new hashes (deploying their services)
319
- // - PUSH and making sure we serve the old UI (when not running --local)
320
- // - Turning off the preloading in deploy, and ensuring it updates
321
- // - ALSO, when the live hash changes, invalidate getCachedConfig?
322
-
323
-
324
- // 5) Write the live hash to the index, and have the client prefer this hash
325
- // - And if it can't be found, fallback to the the hash with the highest bootTime
326
- // (picking from that pool, not just that single node)
327
-
328
328
  // 7) Client live hash watch code + notify + refresh + flag to ignore the baked in live hash + edge node
329
329
  // - Test by pushing, deploying, and then we should immediately see a notify to refresh
330
330