querysub 0.403.0 → 0.405.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/.cursorrules +2 -0
- package/bin/audit-imports.js +4 -0
- package/bin/join.js +1 -1
- package/package.json +7 -4
- package/spec.txt +77 -0
- package/src/-a-archives/archiveCache.ts +9 -4
- package/src/-a-archives/archivesBackBlaze.ts +1039 -1039
- package/src/-a-auth/certs.ts +0 -12
- package/src/-c-identity/IdentityController.ts +12 -3
- package/src/-f-node-discovery/NodeDiscovery.ts +32 -26
- package/src/-g-core-values/NodeCapabilities.ts +12 -2
- package/src/0-path-value-core/AuthorityLookup.ts +239 -0
- package/src/0-path-value-core/LockWatcher2.ts +150 -0
- package/src/0-path-value-core/PathRouter.ts +543 -0
- package/src/0-path-value-core/PathRouterRouteOverride.ts +72 -0
- package/src/0-path-value-core/PathRouterServerAuthoritySpec.tsx +73 -0
- package/src/0-path-value-core/PathValueCommitter.ts +222 -488
- package/src/0-path-value-core/PathValueController.ts +277 -239
- package/src/0-path-value-core/PathWatcher.ts +534 -0
- package/src/0-path-value-core/ShardPrefixes.ts +31 -0
- package/src/0-path-value-core/ValidStateComputer.ts +303 -0
- package/src/0-path-value-core/archiveLocks/ArchiveLocks.ts +1 -1
- package/src/0-path-value-core/archiveLocks/ArchiveLocks2.ts +80 -44
- package/src/0-path-value-core/archiveLocks/archiveSnapshots.ts +13 -16
- package/src/0-path-value-core/auditLogs.ts +2 -0
- package/src/0-path-value-core/hackedPackedPathParentFiltering.ts +97 -0
- package/src/0-path-value-core/pathValueArchives.ts +491 -492
- package/src/0-path-value-core/pathValueCore.ts +195 -1496
- package/src/0-path-value-core/startupAuthority.ts +74 -0
- package/src/1-path-client/RemoteWatcher.ts +90 -82
- package/src/1-path-client/pathValueClientWatcher.ts +808 -815
- package/src/2-proxy/PathValueProxyWatcher.ts +10 -8
- package/src/2-proxy/archiveMoveHarness.ts +182 -214
- package/src/2-proxy/garbageCollection.ts +9 -8
- package/src/2-proxy/schema2.ts +21 -1
- package/src/3-path-functions/PathFunctionHelpers.ts +206 -180
- package/src/3-path-functions/PathFunctionRunner.ts +943 -766
- package/src/3-path-functions/PathFunctionRunnerMain.ts +5 -3
- package/src/3-path-functions/pathFunctionLoader.ts +2 -2
- package/src/3-path-functions/syncSchema.ts +596 -521
- package/src/4-deploy/deployFunctions.ts +19 -4
- package/src/4-deploy/deployGetFunctionsInner.ts +8 -2
- package/src/4-deploy/deployMain.ts +51 -68
- package/src/4-deploy/edgeClientWatcher.tsx +6 -1
- package/src/4-deploy/edgeNodes.ts +2 -2
- package/src/4-dom/qreact.tsx +2 -4
- package/src/4-dom/qreactTest.tsx +7 -13
- package/src/4-querysub/Querysub.ts +21 -8
- package/src/4-querysub/QuerysubController.ts +45 -29
- package/src/4-querysub/permissions.ts +2 -2
- package/src/4-querysub/querysubPrediction.ts +80 -70
- package/src/4-querysub/schemaHelpers.ts +5 -1
- package/src/5-diagnostics/GenericFormat.tsx +14 -9
- package/src/archiveapps/archiveGCEntry.tsx +9 -2
- package/src/archiveapps/archiveJoinEntry.ts +96 -84
- package/src/bits.ts +19 -0
- package/src/config.ts +21 -3
- package/src/config2.ts +23 -48
- package/src/deployManager/components/DeployPage.tsx +7 -3
- package/src/deployManager/machineSchema.ts +4 -1
- package/src/diagnostics/ActionsHistory.ts +3 -8
- package/src/diagnostics/AuditLogPage.tsx +2 -3
- package/src/diagnostics/FunctionCallInfo.tsx +141 -0
- package/src/diagnostics/FunctionCallInfoState.ts +162 -0
- package/src/diagnostics/MachineThreadInfo.tsx +1 -1
- package/src/diagnostics/NodeViewer.tsx +37 -48
- package/src/diagnostics/SyncTestPage.tsx +241 -0
- package/src/diagnostics/auditImportViolations.ts +185 -0
- package/src/diagnostics/listenOnDebugger.ts +3 -3
- package/src/diagnostics/logs/IndexedLogs/BufferUnitSet.ts +10 -4
- package/src/diagnostics/logs/IndexedLogs/IndexedLogs.ts +2 -2
- package/src/diagnostics/logs/IndexedLogs/LogViewer3.tsx +24 -22
- package/src/diagnostics/logs/IndexedLogs/moveIndexLogsToPublic.ts +1 -1
- package/src/diagnostics/logs/diskLogGlobalContext.ts +1 -0
- package/src/diagnostics/logs/errorNotifications2/logWatcher.ts +1 -3
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleEntryEditor.tsx +34 -16
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleEntryReadMode.tsx +4 -6
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleInstanceTableView.tsx +36 -5
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCyclePage.tsx +19 -5
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleRenderer.tsx +15 -7
- package/src/diagnostics/logs/lifeCycleAnalysis/NestedLifeCycleInfo.tsx +28 -106
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycleMatching.ts +2 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycleMisc.ts +0 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycleSearch.tsx +18 -7
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycles.tsx +3 -0
- package/src/diagnostics/managementPages.tsx +10 -3
- package/src/diagnostics/misc-pages/ArchiveViewer.tsx +20 -26
- package/src/diagnostics/misc-pages/ArchiveViewerTree.tsx +6 -4
- package/src/diagnostics/misc-pages/ComponentSyncStats.tsx +2 -2
- package/src/diagnostics/misc-pages/LocalWatchViewer.tsx +7 -9
- package/src/diagnostics/misc-pages/SnapshotViewer.tsx +23 -12
- package/src/diagnostics/misc-pages/archiveViewerShared.tsx +1 -1
- package/src/diagnostics/pathAuditer.ts +486 -0
- package/src/diagnostics/pathAuditerCallback.ts +20 -0
- package/src/diagnostics/watchdog.ts +8 -1
- package/src/library-components/URLParam.ts +1 -1
- package/src/misc/hash.ts +1 -0
- package/src/path.ts +21 -7
- package/src/server.ts +54 -47
- package/src/user-implementation/loginEmail.tsx +1 -1
- package/tempnotes.txt +65 -0
- package/test.ts +298 -97
- package/src/0-path-value-core/NodePathAuthorities.ts +0 -1057
- package/src/0-path-value-core/PathController.ts +0 -1
- package/src/5-diagnostics/diskValueAudit.ts +0 -218
- package/src/5-diagnostics/memoryValueAudit.ts +0 -438
- package/src/archiveapps/archiveMergeEntry.tsx +0 -48
- package/src/archiveapps/lockTest.ts +0 -127
|
@@ -1,239 +1,277 @@
|
|
|
1
|
-
import { SocketFunction } from "socket-function/SocketFunction";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { ActionsHistory } from "../diagnostics/ActionsHistory";
|
|
7
|
-
import { isNode } from "socket-function/src/misc";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
1
|
+
import { SocketFunction } from "socket-function/SocketFunction";
|
|
2
|
+
import { isNodeTrusted, requiresNetworkTrustHook } from "../-d-trust/NetworkTrust2";
|
|
3
|
+
import { PathValue, WriteState, WatchConfig, MAX_CHANGE_AGE, getCompressNetwork, authorityStorage } from "./pathValueCore";
|
|
4
|
+
import { pathWatcher } from "./PathWatcher";
|
|
5
|
+
import { validStateComputer } from "./ValidStateComputer";
|
|
6
|
+
import { ActionsHistory } from "../diagnostics/ActionsHistory";
|
|
7
|
+
import { isNode, nextId, timeInSecond, timeoutToUndefined } from "socket-function/src/misc";
|
|
8
|
+
import { pathValueSerializer } from "../-h-path-value-serialize/PathValueSerializer";
|
|
9
|
+
import { pathValueCommitter } from "./PathValueCommitter";
|
|
10
|
+
import { Benchmark } from "../diagnostics/benchmark";
|
|
11
|
+
import { auditLog, isDebugLogEnabled } from "./auditLogs";
|
|
12
|
+
import { debugNodeId, debugNodeThread } from "../-c-identity/IdentityController";
|
|
13
|
+
import { isDiskAudit } from "../config";
|
|
14
|
+
import { decodeNodeId } from "../-a-auth/certs";
|
|
15
|
+
import { areNodeIdsEqual, isOwnNodeId } from "../-f-node-discovery/NodeDiscovery";
|
|
16
|
+
import { getNodeIdIP } from "socket-function/src/nodeCache";
|
|
17
|
+
import { authorityLookup } from "./AuthorityLookup";
|
|
18
|
+
import { timeoutToError } from "../errors";
|
|
19
|
+
import { AuthoritySpec, PathRouter } from "./PathRouter";
|
|
20
|
+
export { pathValueCommitter };
|
|
21
|
+
|
|
22
|
+
// The sync test page has some functions which related to PathValueController significantly, and should always be exposed if PathValueController is exposed.
|
|
23
|
+
if (isNode()) {
|
|
24
|
+
setImmediate(() => {
|
|
25
|
+
import("../diagnostics/SyncTestPage");
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// NOTE: initialTriggers = clobber values on these paths (or all children of a parent), And take the values that we've provided. This allows you to get a client into a nice state by just saying, I don't know what you had before from other servers, but drop all that. Here's the correct state.
|
|
31
|
+
|
|
32
|
+
export class PathValueControllerBase {
|
|
33
|
+
public static async createValues(config: {
|
|
34
|
+
nodeId: string;
|
|
35
|
+
pathValues: PathValue[];
|
|
36
|
+
}): Promise<void | "refused"> {
|
|
37
|
+
const { Querysub } = await import("../4-querysub/Querysub");
|
|
38
|
+
let { pathValues, nodeId } = config;
|
|
39
|
+
|
|
40
|
+
let serializedValues = await pathValueSerializer.serialize(pathValues, { compress: Querysub.COMPRESS_NETWORK });
|
|
41
|
+
if (isDebugLogEnabled()) {
|
|
42
|
+
for (let value of pathValues) {
|
|
43
|
+
auditLog("SEND CREATED VALUE", {
|
|
44
|
+
path: value.path,
|
|
45
|
+
timeId: value.time.time,
|
|
46
|
+
targetNodeThreadId: debugNodeThread(nodeId),
|
|
47
|
+
transparent: value.isTransparent,
|
|
48
|
+
source: value.source,
|
|
49
|
+
totalValues: pathValues.length,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return await PathValueController.nodes[nodeId].sendData({
|
|
54
|
+
valueBuffers: serializedValues,
|
|
55
|
+
initialCreation: true,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
private static logSendValues(config: {
|
|
59
|
+
nodeId: string;
|
|
60
|
+
pathValues: PathValue[];
|
|
61
|
+
initialTriggers?: { values: Set<string>; parentPaths: Set<string> },
|
|
62
|
+
}) {
|
|
63
|
+
let { nodeId, pathValues, initialTriggers } = config;
|
|
64
|
+
if (isDebugLogEnabled()) {
|
|
65
|
+
for (let pathValue of pathValues) {
|
|
66
|
+
auditLog("SEND VALUE", {
|
|
67
|
+
path: pathValue.path,
|
|
68
|
+
timeId: pathValue.time.time,
|
|
69
|
+
watcher: nodeId,
|
|
70
|
+
isValid: pathValue.valid,
|
|
71
|
+
nodeId: debugNodeId(nodeId),
|
|
72
|
+
targetNodeId: debugNodeId(nodeId),
|
|
73
|
+
targetNodeThreadId: debugNodeThread(nodeId),
|
|
74
|
+
transparent: pathValue.isTransparent,
|
|
75
|
+
canGC: pathValue.canGCValue,
|
|
76
|
+
initialTrigger: initialTriggers?.values.has(pathValue.path),
|
|
77
|
+
triggerId: nextId(),
|
|
78
|
+
totalChanges: pathValues.length,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
public static async sendValues(config: {
|
|
84
|
+
nodeId: string;
|
|
85
|
+
pathValues: PathValue[];
|
|
86
|
+
initialTriggers?: { values: Set<string>; parentPaths: Set<string> },
|
|
87
|
+
}) {
|
|
88
|
+
let changes = config.pathValues;
|
|
89
|
+
let { nodeId, initialTriggers } = config;
|
|
90
|
+
let allowSource = await isNodeTrusted(nodeId) || getNodeIdIP(nodeId) === "127.0.0.1";
|
|
91
|
+
let buffers = await pathValueSerializer.serialize(changes, {
|
|
92
|
+
noLocks: true,
|
|
93
|
+
compress: getCompressNetwork(),
|
|
94
|
+
stripSource: !allowSource,
|
|
95
|
+
});
|
|
96
|
+
this.logSendValues({ nodeId, pathValues: changes, initialTriggers, });
|
|
97
|
+
return await PathValueController.nodes[nodeId].sendData({
|
|
98
|
+
valueBuffers: buffers,
|
|
99
|
+
initialTriggers: initialTriggers,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public async sendData(config: {
|
|
104
|
+
// If it's the initial creation, then we can actually reject them. However, we do need to provide a rejection pathway for the client side to know that we have accepted none of the changes and that it should remove them locally.
|
|
105
|
+
initialCreation?: boolean;
|
|
106
|
+
|
|
107
|
+
valueBuffers?: Buffer[];
|
|
108
|
+
initialTriggers?: {
|
|
109
|
+
/** This means that we will provided the full history for all these paths. If you have any other history, it should be removed. */
|
|
110
|
+
values: Set<string>;
|
|
111
|
+
/** This means that we will have provided all of the child values for these parent paths, and so if you have any child values which were not provided in our value list, those values should be removed. */
|
|
112
|
+
parentPaths: Set<string>;
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
}): Promise<void | "refused"> {
|
|
116
|
+
let callerId = SocketFunction.getCaller().nodeId;
|
|
117
|
+
let { initialCreation, valueBuffers } = config;
|
|
118
|
+
|
|
119
|
+
let values: PathValue[] = [];
|
|
120
|
+
if (valueBuffers) {
|
|
121
|
+
values = await pathValueSerializer.deserialize(valueBuffers);
|
|
122
|
+
Benchmark.onReceivedValues(values);
|
|
123
|
+
ActionsHistory.OnRead(values);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (initialCreation) {
|
|
127
|
+
let sourceNodeId = debugNodeId(callerId);
|
|
128
|
+
let rejected = false;
|
|
129
|
+
let threshold = Date.now() - MAX_CHANGE_AGE;
|
|
130
|
+
for (let value of values) {
|
|
131
|
+
let pastThreshold = threshold - value.time.time;
|
|
132
|
+
if (pastThreshold > 0) {
|
|
133
|
+
rejected = true;
|
|
134
|
+
console.error(`Rejecting values as one is too old. It likely got caught in the pipeline too long and now can't be committed without trying to undone history which can already been committed to disk.`, {
|
|
135
|
+
path: value.path,
|
|
136
|
+
timeId: value.time.time,
|
|
137
|
+
sourceNodeId,
|
|
138
|
+
sourceNodeThreadId: decodeNodeId(sourceNodeId)?.threadId,
|
|
139
|
+
totalValueCount: values.length,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (rejected) {
|
|
144
|
+
return "refused";
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (isDebugLogEnabled() || isDiskAudit()) {
|
|
149
|
+
let sourceNodeId = debugNodeId(callerId);
|
|
150
|
+
for (let value of values) {
|
|
151
|
+
auditLog("RECEIVE VALUE", {
|
|
152
|
+
path: value.path,
|
|
153
|
+
// NOTE: Yes, this might conflict as we're throwing away a lot of information, however in practice no, it's not going to conflict when we're debugging, and this + path will be globally unique for every value we investigate.
|
|
154
|
+
timeId: value.time.time,
|
|
155
|
+
sourceNodeId,
|
|
156
|
+
sourceNodeThreadId: decodeNodeId(sourceNodeId)?.threadId,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
let parentSyncs = Array.from(config.initialTriggers?.parentPaths || [])
|
|
163
|
+
.map(x => ({ parentPath: x, sourceNodeId: callerId }));
|
|
164
|
+
let initialTriggers = config.initialTriggers || { values: new Set(), parentPaths: new Set() };
|
|
165
|
+
validStateComputer.ingestValuesAndValidStates({
|
|
166
|
+
pathValues: values,
|
|
167
|
+
parentSyncs,
|
|
168
|
+
initialTriggers,
|
|
169
|
+
});
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.error("Error ingesting values and valid states", error);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if (config.initialCreation) {
|
|
176
|
+
// NOTE: This will mean that all of the authorities for a value will write it to disk. So it will be written to disk multiple times. This should be fine, and it might be a good idea for redundancy, etc. And eventually, they will get compressed to one value, so it's not inefficient.
|
|
177
|
+
await PathValueControllerBase.authorityShareValues({ pathValues: values });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public static async authorityShareValues(config: {
|
|
182
|
+
pathValues: PathValue[];
|
|
183
|
+
}) {
|
|
184
|
+
let { pathValues } = config;
|
|
185
|
+
let valuesPerOtherAuthority = PathRouter.getAllAuthoritiesForValues(pathValues);
|
|
186
|
+
let promises = Array.from(valuesPerOtherAuthority.entries()).map(async ([otherAuthority, values]) => {
|
|
187
|
+
try {
|
|
188
|
+
await timeoutToError(timeInSecond * 15, PathValueControllerBase.sendValues({
|
|
189
|
+
nodeId: otherAuthority,
|
|
190
|
+
pathValues: values,
|
|
191
|
+
}), () => new Error(`Timeout forwarding shared values (${values.length} values) to authority ${otherAuthority}`));
|
|
192
|
+
} catch (error: any) {
|
|
193
|
+
console.error(error.message, { otherAuthority, count: values.length });
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
await Promise.all(promises);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
public async watchLatest(config: WatchConfig) {
|
|
201
|
+
let callerId = SocketFunction.getCaller().nodeId;
|
|
202
|
+
if (isDebugLogEnabled()) {
|
|
203
|
+
let sourceNodeId = debugNodeId(callerId);
|
|
204
|
+
for (let value of config.paths) {
|
|
205
|
+
auditLog("WATCH PATH", { path: value, sourceNodeId, sourceNodeThreadId: debugNodeThread(callerId) });
|
|
206
|
+
}
|
|
207
|
+
for (let value of config.parentPaths) {
|
|
208
|
+
auditLog("WATCH PARENT PATH", { path: value, sourceNodeId });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
pathWatcher.watchPath({
|
|
212
|
+
nodeId: callerId,
|
|
213
|
+
paths: config.paths,
|
|
214
|
+
parentPaths: config.parentPaths,
|
|
215
|
+
initialTrigger: true,
|
|
216
|
+
fullHistory: config.fullHistory,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
public async unwatchLatest(config: WatchConfig) {
|
|
220
|
+
let callerId = SocketFunction.getCaller().nodeId;
|
|
221
|
+
if (isDebugLogEnabled()) {
|
|
222
|
+
let sourceNodeId = debugNodeId(SocketFunction.getCaller().nodeId);
|
|
223
|
+
for (let value of config.paths) {
|
|
224
|
+
auditLog("UNWATCHING PATH", { path: value, sourceNodeId, sourceNodeThreadId: debugNodeThread(callerId) });
|
|
225
|
+
}
|
|
226
|
+
for (let value of config.parentPaths) {
|
|
227
|
+
auditLog("UNWATCHING PARENT PATH", { path: value, sourceNodeId });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
pathWatcher.unwatchPath({ paths: config.paths, parentPaths: config.parentPaths, callback: callerId });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
public static async getInitialValues(config: {
|
|
234
|
+
nodeId: string;
|
|
235
|
+
spec: AuthoritySpec;
|
|
236
|
+
// Only returns values with a create time in this window
|
|
237
|
+
startTime: number;
|
|
238
|
+
endTime: number;
|
|
239
|
+
}): Promise<PathValue[]> {
|
|
240
|
+
let buffers = await PathValueController.nodes[config.nodeId].getInitialValues(config);
|
|
241
|
+
return await pathValueSerializer.deserialize(buffers);
|
|
242
|
+
}
|
|
243
|
+
// NOTE: Sends all the responses using the regular
|
|
244
|
+
public async getInitialValues(config: {
|
|
245
|
+
spec: AuthoritySpec;
|
|
246
|
+
// Only returns values with a create time in this window
|
|
247
|
+
startTime: number;
|
|
248
|
+
endTime: number;
|
|
249
|
+
}): Promise<Buffer[]> {
|
|
250
|
+
let values = authorityStorage.getAllValues(config);
|
|
251
|
+
let buffers = await pathValueSerializer.serialize(values, {
|
|
252
|
+
noLocks: true,
|
|
253
|
+
compress: getCompressNetwork(),
|
|
254
|
+
});
|
|
255
|
+
return buffers;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export const PathValueController = SocketFunction.register(
|
|
260
|
+
"PathValueController-1e062e2c-81c9-497b-b414-a46d0a4c2313",
|
|
261
|
+
new PathValueControllerBase(),
|
|
262
|
+
() => ({
|
|
263
|
+
sendData: {},
|
|
264
|
+
|
|
265
|
+
getInitialValues: {},
|
|
266
|
+
|
|
267
|
+
watchLatest: {},
|
|
268
|
+
unwatchLatest: {},
|
|
269
|
+
}),
|
|
270
|
+
() => ({
|
|
271
|
+
hooks: [requiresNetworkTrustHook],
|
|
272
|
+
}),
|
|
273
|
+
{
|
|
274
|
+
noFunctionMeasure: !isNode(),
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
|