querysub 0.402.0 → 0.404.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/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 +535 -0
- package/src/0-path-value-core/PathRouterRouteOverride.ts +72 -0
- package/src/0-path-value-core/PathRouterServerAuthoritySpec.tsx +65 -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 +490 -492
- package/src/0-path-value-core/pathValueCore.ts +195 -1492
- package/src/0-path-value-core/startupAuthority.ts +74 -0
- package/src/1-path-client/RemoteWatcher.ts +100 -83
- 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 +592 -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 +1 -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 +87 -84
- package/src/archiveapps/archiveMergeEntry.tsx +2 -0
- 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 +39 -17
- 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 +67 -0
- package/test.ts +288 -95
- 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/lockTest.ts +0 -127
package/src/server.ts
CHANGED
|
@@ -1,48 +1,55 @@
|
|
|
1
|
-
import "./forceProduction";
|
|
2
|
-
import "./inject";
|
|
3
|
-
|
|
4
|
-
import { isNode, isNodeTrue } from "socket-function/src/misc";
|
|
5
|
-
import { SocketFunction } from "socket-function/SocketFunction";
|
|
6
|
-
import { getThreadKeyCert } from "./-a-auth/certs";
|
|
7
|
-
import { logErrors } from "./errors";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
import {
|
|
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
|
-
|
|
1
|
+
import "./forceProduction";
|
|
2
|
+
import "./inject";
|
|
3
|
+
|
|
4
|
+
import { isNode, isNodeTrue } from "socket-function/src/misc";
|
|
5
|
+
import { SocketFunction } from "socket-function/SocketFunction";
|
|
6
|
+
import { getThreadKeyCert } from "./-a-auth/certs";
|
|
7
|
+
import { logErrors } from "./errors";
|
|
8
|
+
import { green } from "socket-function/src/formatting/logColors";
|
|
9
|
+
import { formatTime } from "socket-function/src/formatting/format";
|
|
10
|
+
|
|
11
|
+
// As nice as it is that Querysub doesn't get imported, because our import hierarchy is so strict...
|
|
12
|
+
// we DO want to register some static diagnostics from Querysub, so... import it explicitly.
|
|
13
|
+
import "./4-querysub/Querysub";
|
|
14
|
+
|
|
15
|
+
import { Querysub } from "./4-querysub/Querysub";
|
|
16
|
+
import { getDomain, isPublic } from "./config";
|
|
17
|
+
import { enableDebugRejections } from "./0-path-value-core/pathValueCore";
|
|
18
|
+
import { AuthoritySpec, PathRouter } from "./0-path-value-core/PathRouter";
|
|
19
|
+
import { authorityLookup } from "./0-path-value-core/AuthorityLookup";
|
|
20
|
+
import { startupAuthority } from "./0-path-value-core/startupAuthority";
|
|
21
|
+
import { getOurAuthoritySpec } from "./0-path-value-core/PathRouterServerAuthoritySpec";
|
|
22
|
+
|
|
23
|
+
logErrors(main());
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
if (!isNode()) return;
|
|
27
|
+
|
|
28
|
+
console.log(`Time before main ${green(formatTime(process.uptime() * 1000))}`);
|
|
29
|
+
|
|
30
|
+
Error.stackTraceLimit = 20;
|
|
31
|
+
|
|
32
|
+
// SocketFunction.logMessages = true;
|
|
33
|
+
// SocketFunction.silent = false;
|
|
34
|
+
|
|
35
|
+
// ClientWatcher.DEBUG_READS = true;
|
|
36
|
+
// ClientWatcher.DEBUG_WRITES = true;
|
|
37
|
+
|
|
38
|
+
SocketFunction.WIRE_WARN_TIME = 50;
|
|
39
|
+
|
|
40
|
+
//setMaxChangeAge(1000 * 15);
|
|
41
|
+
|
|
42
|
+
//ActionsHistory.LOG_ACTION_HISTORY = "server";
|
|
43
|
+
|
|
44
|
+
//debugCoreMode();
|
|
45
|
+
if (!isPublic()) {
|
|
46
|
+
enableDebugRejections();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await Querysub.hostService("PathValueServer");
|
|
50
|
+
|
|
51
|
+
let spec = await getOurAuthoritySpec(true);
|
|
52
|
+
if (spec) {
|
|
53
|
+
await startupAuthority(spec);
|
|
54
|
+
}
|
|
48
55
|
}
|
|
@@ -79,7 +79,7 @@ export function generateLoginEmail(config: {
|
|
|
79
79
|
</table>
|
|
80
80
|
{line(<div style={{ color: "rgb(255, 255, 255)" }}>
|
|
81
81
|
{/* Mess up the email so it isn't turned into a link by gmail. */}
|
|
82
|
-
|
|
82
|
+
Hi <b>{email.replaceAll(".", ".")}</b>. You have requested access to <a href={redirectURL} style={{ color: "rgb(153, 204, 255)" }}>{new URL(redirectURL).hostname}</a>.
|
|
83
83
|
</div>)}
|
|
84
84
|
{line(<div style={{ color: "rgb(255, 255, 255)" }}>
|
|
85
85
|
If you did not make this request, please disregard this email. Your account is safe and no action is required.
|
package/tempnotes.txt
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
BUGS:
|
|
3
|
+
FIXED? The value audit code says that the servers are missing values, And it's trying to send the test values between the different path value servers, even though they should be sharded to never share values.
|
|
4
|
+
FIXED? The CYOA server keeps locking up
|
|
5
|
+
█ PathValueSerializer() 46.34% ( 66.6s = 75.3K * 765us + 550K * 16.3us )
|
|
6
|
+
- The values keep syncing to both servers.
|
|
7
|
+
FIXED? The CYOA and the function server keep failing the audits as well. We might need to look at the logs to see how this could happen. It'll probably be obvious once we look at the logs for those paths.
|
|
8
|
+
- Is it because we're unwatching it? That would make a lot of sense.
|
|
9
|
+
- I guess we can just step in and see if its watched
|
|
10
|
+
pathWatcher.watchers.get(path)
|
|
11
|
+
remoteWatcher.remoteWatchPaths.get(path)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
4) deploy ON THE SITE, to deploy our prefixes
|
|
16
|
+
- Do it via the site, to commit, publish, etc.
|
|
17
|
+
3) gc, to split it into multiple directories
|
|
18
|
+
4) Verify the site still works
|
|
19
|
+
|
|
20
|
+
5) Verify that the sharded startup only loads in the paths it needs and isn't wasteful
|
|
21
|
+
- With 100 granularity the waste should be quite low. Unless we get REALLY unlucky? Hmm...
|
|
22
|
+
|
|
23
|
+
6) Record path waste per PathValueServer, and add an admin warn component that requests this, then shows a warning for PathValueServers that have a high waste load %
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
3) Test sharding again
|
|
27
|
+
4) Verify the test page works well, and shards
|
|
28
|
+
- We have the function sharding, so the values shouldn't be sent to both servers because the function calls themselves should be sharded.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
5) Test full path hash syncing, using data that's NOT in a prefix, and making sure we can sync it with keys to get some of it (and all of it)
|
|
32
|
+
a) When connecting from a trusted node, everything should work fine, the flag should pass through correctly, as remote watchers should know what flag to pass.
|
|
33
|
+
b) When syncing from the client side, only synchronizing all the keys will work. But that does still need to work, and that still requires talking to the correct nodes and passing them the correct flags.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
3) add code so that client-side we can get a breakdown of How many paths we have per authority. The goal is to just have most the paths come from a single authority. For reading, it's actually more efficient to talk to a single server rather than many servers, as it's not the amount of data, it's really just the latency overhead of talking to the server. And for writing, same thing, it's a lot easier to just write to one server. And if every single user is reading from every single server, it's just not feasible. It no longer scales well.
|
|
37
|
+
|
|
38
|
+
4) Get the AI to go through and add function remapping code. Basically, the idea is that we take the most accessed lookup that we're accessing and we use the key for that as our hash. For simple functions, we could actually automate this, but I'll see how the AI can do.
|
|
39
|
+
|
|
40
|
+
5) Verify we are mostly accessing paths on one authority
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
7) Test 4 servers, sharded and redundant as the same time
|
|
44
|
+
8) Verify on the test page
|
|
45
|
+
|
|
46
|
+
8) Shard FunctionRunner
|
|
47
|
+
- Now is as good a time as any to deal with any of the sharding issues. And it should work easily enough...
|
|
48
|
+
- Verify the secondary run backup code works too.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
2) Add disk verification service
|
|
52
|
+
- pick a random authority => read the same we would as startup => do an extra backblaze getKeys and getInfo to make sure our cache is accurate => load in the data into memory => verify all old paths with that authority?
|
|
53
|
+
- I wasn't planning on verifying all paths, but we should be able to. They have to be old enough, of course. But we kind of already have that logic, so the AI can probably write it. The one somewhat hard thing, of course, is doing the hashes, especially because new data could cause the hashes to change because of GCing in memory. But if that's the case, for now we can error. Eventually we will warn and then we will drill down further to find the specific paths that are wrong. And if they actually are wrong, then we can actually error.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
2) Allow remote servers to talk to our local server, via using the connection the local server makes
|
|
57
|
+
AH! Add a connectivity page that we can go to, and you can tell all the servers to ping all the other servers, and then it will give us a full list of all that are inaccessible. We should start with this page, deploy it, Then witness that the remote server can't talk to our local servers. They don't even need to be local path value servers, just our local CYOA server, etc.
|
|
58
|
+
I think what we need to do is we need to group connections by the resolved identity instead of by the underlying node ID. Maybe this is already done? (But I don't remember doing it).
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
3) Deploy EVERYTHING (all services) to remote servers
|
|
63
|
+
3.0) deploy the path value servers shard it like we were testing locally
|
|
64
|
+
- 4, for redundancy and sharding
|
|
65
|
+
5) Deploy disk verification service
|
|
66
|
+
|
|
67
|
+
|
package/test.ts
CHANGED
|
@@ -3,109 +3,302 @@ chdir("D:/repos/qs-cyoa/");
|
|
|
3
3
|
|
|
4
4
|
import "./inject";
|
|
5
5
|
|
|
6
|
+
import { list, sort } from "socket-function/src/misc";
|
|
7
|
+
import { formatNumber } from "socket-function/src/formatting/format";
|
|
8
|
+
import { PathValueArchives, archives, archivesLocks, archivesRecycleBin, pathValueArchives } from "./src/0-path-value-core/pathValueArchives";
|
|
9
|
+
import { trimPathStrToDepth } from "./src/path";
|
|
6
10
|
import { Querysub } from "./src/4-querysub/QuerysubController";
|
|
7
|
-
import {
|
|
8
|
-
import { watchAllValues } from "./src/diagnostics/logs/errorNotifications2/logWatcher";
|
|
9
|
-
import { SocketFunction } from "socket-function/SocketFunction";
|
|
10
|
-
import fs from "fs";
|
|
11
|
-
import { getControllerNodeId, getControllerNodeIdList } from "./src/-g-core-values/NodeCapabilities";
|
|
11
|
+
import { clientWatcher } from "./src/1-path-client/pathValueClientWatcher";
|
|
12
12
|
import { delay } from "socket-function/src/batching";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
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[] = [];
|
|
13
|
+
import { authorityStorage } from "./src/0-path-value-core/pathValueCore";
|
|
14
|
+
import { authorityLookup } from "./src/0-path-value-core/AuthorityLookup";
|
|
15
|
+
import { getSnapshot, loadSnapshot, saveSnapshot } from "./src/0-path-value-core/archiveLocks/archiveSnapshots";
|
|
16
|
+
import { Transaction } from "./src/0-path-value-core/archiveLocks/ArchiveLocks2";
|
|
17
|
+
import { getArchives } from "./src/-a-archives/archives";
|
|
18
|
+
import { unique } from "./src/misc";
|
|
19
|
+
import { getAllAuthoritySpec, getOurAuthoritySpec } from "./src/0-path-value-core/PathRouterServerAuthoritySpec";
|
|
20
|
+
import { PathRouter } from "./src/0-path-value-core/PathRouter";
|
|
21
|
+
import { pathValueSerializer } from "./src/-h-path-value-serialize/PathValueSerializer";
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
let paths = await pathValueArchives.getValuePaths(getAllAuthoritySpec());
|
|
25
|
+
paths = paths.filter(x => x.startsWith("P!REMAINING/"));
|
|
68
26
|
for (let path of paths) {
|
|
69
|
-
let data = await
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
27
|
+
let data = await archives().get(path);
|
|
28
|
+
if (!data) {
|
|
29
|
+
console.log(`Missing data file: ${path}`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
let loadObj = await PathValueArchives.loadValuesFromBuffer({ path, data });
|
|
74
33
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
34
|
+
for (let value of loadObj.values) {
|
|
35
|
+
if (!PathRouter.matchesAuthoritySpec(getAllAuthoritySpec(), value.path)) {
|
|
36
|
+
throw new Error(`Value ${value.path} does not match authority spec`);
|
|
37
|
+
}
|
|
38
|
+
console.log(pathValueSerializer.getPathValue(value));
|
|
39
|
+
}
|
|
78
40
|
}
|
|
79
|
-
|
|
41
|
+
return;
|
|
42
|
+
|
|
43
|
+
// let path = "P!REMAINING/data_37c5d323e0f9a083.1ed7a7340a015680.querysubtest.com:52026_1775097754671.579_3_1_337_1775097652829.5793_1775097652829.5793_genesis_.data";
|
|
44
|
+
// let value = await archives().get(path);
|
|
45
|
+
// console.log(value?.toString());
|
|
46
|
+
// return;
|
|
47
|
+
|
|
48
|
+
// const path = list(500).map(x => "a").join("");
|
|
49
|
+
// await archives().set(path, Buffer.from("Hello, world!"));
|
|
50
|
+
// let value = await archives().get(path);
|
|
51
|
+
// console.log(value?.toString());
|
|
52
|
+
|
|
53
|
+
// function getName(path: string): string {
|
|
54
|
+
// return path.split("/").at(-1)!;
|
|
55
|
+
// }
|
|
56
|
+
|
|
57
|
+
let allValuesObj = await pathValueArchives.loadValues({
|
|
58
|
+
nodeId: "",
|
|
59
|
+
prefixes: [],
|
|
60
|
+
routeStart: 0,
|
|
61
|
+
routeEnd: 1,
|
|
62
|
+
});
|
|
63
|
+
let allValues = Object.values(allValuesObj.values).flat();
|
|
64
|
+
console.log(`Total values loaded: ${formatNumber(allValues.length)}`);
|
|
65
|
+
|
|
66
|
+
// const badDeleteTransaction = "transaction_ tSeqNum=887 tWriteTime=1774715868374.9143 thread=9dc0 cCount=14 dCount=3482 create=X,X,X,X,X,X,X,X,X,X,X,X,X,X delete=2@0977,3@0977,4@0977,1@0a2a,2@0a2a,3@0a2a,4@0a2... .transaction";
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
// // const snapshotFile = "fileCount=3482 valueCount=1142614 byteCount=1074547019 time=1774724950047.202 hash=9d9acc132ccfbf898ae0c287391e48a88e4e3b3ed3beda16f81a0936e710ab07";
|
|
70
|
+
// // const snapshotFile2 = "fileCount=51 valueCount=1040817 byteCount=1019830353 time=1772831139982.38 hash=7c6acb6b705a8c68892f787e9c9f958b527bde8b60fb914045863a4bedc269e7";
|
|
71
|
+
// const fixedSnapshotFile = "fileCount=3482 valueCount=1142614 byteCount=1074547019 time=1774760576390.8218 hash=6ef29678cb600f6920d1615c265ff5150ba97c847143fae2832e26d9e1adf1cf";
|
|
72
|
+
// let snapshotFileObj = await getSnapshot(fixedSnapshotFile);
|
|
73
|
+
|
|
74
|
+
// // let files: string[] = [];
|
|
75
|
+
// // for (let file of snapshotFileObj.files) {
|
|
76
|
+
// // files.push("NEW_remaining/" + getName(file.file));
|
|
77
|
+
// // }
|
|
78
|
+
// // let joinedSnapshot = await saveSnapshot({ files });
|
|
79
|
+
// // console.log(`Joined snapshot: ${joinedSnapshot.file}`);
|
|
80
|
+
// //await loadSnapshot({ overview: { file: fixedSnapshotFile }, noExit: true, hackNoDelete: true });
|
|
81
|
+
|
|
82
|
+
// let snapshot = await getSnapshot(fixedSnapshotFile);
|
|
83
|
+
// let found = 0;
|
|
84
|
+
// let recycleBin = 0;
|
|
85
|
+
// for (let file of snapshot.files) {
|
|
86
|
+
// let data = await archives().get(file.file);
|
|
87
|
+
// if (data) {
|
|
88
|
+
// found++;
|
|
89
|
+
// console.log("Found");
|
|
90
|
+
// } else if (await archivesRecycleBin().get(file.file)) {
|
|
91
|
+
// recycleBin++;
|
|
92
|
+
// console.log("Found in recycle bin");
|
|
93
|
+
// } else {
|
|
94
|
+
// console.log("MISSING!");
|
|
95
|
+
// }
|
|
96
|
+
// }
|
|
97
|
+
// // console.log(`Found ${found}/${snapshot.files.length} files | Recycle bin: ${recycleBin}`);
|
|
80
98
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
//await loadSnapshot({ overview: { file: fixedSnapshotFile }, noExit: true, hackNoDelete: true });
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// // let joinedFiles = unique([...snapshot1.files, ...snapshot2.files].map(x => x.file));
|
|
104
|
+
// // require("debugbreak")(2);
|
|
105
|
+
// // debugger;
|
|
106
|
+
// // let joinedSnapshot = await saveSnapshot({ files: joinedFiles });
|
|
107
|
+
// // console.log(`Joined snapshot: ${joinedSnapshot.file}`);
|
|
108
|
+
// // let joinedSnapshotFile = "fileCount=3482 valueCount=1142614 byteCount=1074547019 time=1774745293898.8706 hash=9d9acc132ccfbf898ae0c287391e48a88e4e3b3ed3beda16f81a0936e710ab07";
|
|
109
|
+
// // joinedSnapshotFile = snapshotFile2;
|
|
110
|
+
|
|
111
|
+
// // await loadSnapshot({ overview: { file: snapshotFile2 }, noExit: true, hackNoDelete: true });
|
|
112
|
+
|
|
113
|
+
/*
|
|
114
|
+
let allFiles = await getArchives("").find("");
|
|
115
|
+
let allFileNames = new Set(allFiles.map(getName));
|
|
116
|
+
|
|
117
|
+
let joinedSnapshot = await getSnapshot(snapshotFile2);
|
|
118
|
+
|
|
119
|
+
let countByExtension = new Map<string, { value: number }>();
|
|
120
|
+
let found = 0;
|
|
121
|
+
let recycleBin = 0;
|
|
122
|
+
for (let file of joinedSnapshot.files) {
|
|
123
|
+
let extension = file.file.split(".").pop() || "";
|
|
124
|
+
let existing = countByExtension.get(extension);
|
|
125
|
+
if (!existing) {
|
|
126
|
+
existing = { value: 0 };
|
|
127
|
+
countByExtension.set(extension, existing);
|
|
128
|
+
}
|
|
129
|
+
existing.value++;
|
|
130
|
+
let data = await archives().get(file.file);
|
|
131
|
+
if (data) {
|
|
132
|
+
found++;
|
|
133
|
+
} else if (await archivesRecycleBin().get(file.file)) {
|
|
134
|
+
recycleBin++;
|
|
135
|
+
} else if (allFileNames.has(getName(file.file))) {
|
|
136
|
+
require("debugbreak")(2);
|
|
137
|
+
debugger;
|
|
138
|
+
}
|
|
90
139
|
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
140
|
+
console.log(Array.from(countByExtension.entries()).map(([extension, value]) => `${extension}: ${value.value}`).join(" | "));
|
|
141
|
+
console.log(`Found ${found}/${joinedSnapshot.files.length} files | Recycle bin: ${recycleBin}`);
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
//*/
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
// let joined = await saveSnapshot({ files: joinedFiles });
|
|
148
|
+
// console.log(`Joined snapshot: ${joined.file}`);
|
|
149
|
+
|
|
150
|
+
// let recycleBinFiles = await archivesRecycleBin().find("");
|
|
151
|
+
|
|
152
|
+
// //let snapshot = await getSnapshot(snapshotFile);
|
|
153
|
+
//await loadSnapshot({ overview: { file: joinedSnapshotFile }, noExit: true, hackNoDelete: true });
|
|
154
|
+
// require("debugbreak")(2);
|
|
155
|
+
// debugger;
|
|
156
|
+
|
|
157
|
+
//Ugh... we restored... SOME values. 34.4K. But we should have restored over 1 million. And... it doesn't work, of course.
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
//let recycleBinFiles = await archivesRecycleBin().find("");
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
{
|
|
164
|
+
let snapshot = await getSnapshot(joinedSnapshotFile);
|
|
165
|
+
let snapshotNames = new Set(snapshot.files.map(x => getName(x.file)));
|
|
166
|
+
|
|
167
|
+
let archivesRoot = getArchives("");
|
|
168
|
+
let allFiles = await archivesRoot.find("");
|
|
169
|
+
let fullPaths = allFiles.filter(x => snapshotNames.has(getName(x)));
|
|
170
|
+
let correct = 0;
|
|
171
|
+
let wrong = 0;
|
|
172
|
+
let duplicate = 0;
|
|
173
|
+
let foundPaths = new Set<string>();
|
|
174
|
+
for (let i = 0; i < fullPaths.length; i++) {
|
|
175
|
+
let fullPath = fullPaths[i];
|
|
176
|
+
let name = getName(fullPath);
|
|
177
|
+
let correctPath = `path-values-recycle-bin/NEW_remaining/${name}`;
|
|
178
|
+
if (fullPath === correctPath) {
|
|
179
|
+
correct++;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
wrong++;
|
|
183
|
+
if (foundPaths.has(name)) {
|
|
184
|
+
duplicate++;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
console.log(`Path is wrong at ${i}/${fullPaths.length}: ${fullPath}`);
|
|
188
|
+
foundPaths.add(name);
|
|
189
|
+
await archivesRoot.move({
|
|
190
|
+
path: fullPath,
|
|
191
|
+
targetPath: correctPath,
|
|
192
|
+
target: archivesRoot,
|
|
193
|
+
});
|
|
106
194
|
}
|
|
107
|
-
|
|
195
|
+
console.log({ correct, wrong, duplicate, snapshotCount: snapshot.files.length, allCount: allFiles.length, fullPathsCount: fullPaths.length });
|
|
108
196
|
}
|
|
197
|
+
|
|
198
|
+
//*/
|
|
199
|
+
|
|
200
|
+
// let recycleBinValues = await archivesRecycleBin().findInfo("");
|
|
201
|
+
// require("debugbreak")(2);
|
|
202
|
+
// debugger;
|
|
203
|
+
|
|
204
|
+
// // File =-.,querysubtest._com.,/data_0ee02faf16c0fadf.1ed7a7340a015680.querysubtest.com:58985_1773251893137_6_1_337_1773251743670_1773251743670_genesis_.data is not in the recycle bin, skipping
|
|
205
|
+
|
|
206
|
+
// // UGH... they values we delete are not in the recycle bin? Wtf...
|
|
207
|
+
// // Welp... files ARE KEPT after deletion natively, so maybe we can find them that way
|
|
208
|
+
|
|
209
|
+
// //todonext
|
|
210
|
+
// // "move" must be broken? Hmm...
|
|
211
|
+
|
|
212
|
+
// // HMM... Why do we have all these files in the root? That is surely not correct. These kinda look like our restored snapshot...
|
|
213
|
+
// // That would make sense if move lost its ability to nest values. Maybe due to our caching?
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
// //let snapshot = await getSnapshot(snapshotFile);
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
// let test = await archives().find("");
|
|
222
|
+
// console.log(test.length);
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
// We have 125K paths in the recycle bin. We read it surprisingly fast (2 minutes), but yeah... we need to fix this...
|
|
227
|
+
// So... archivesRecycleBin is VERY slow. Hmm... do we ever clean it up? I think we have to?
|
|
228
|
+
// - We will want to thin the snapshots, not just remove all old ones.
|
|
229
|
+
// Hmm... So what even happened?
|
|
230
|
+
// - We have some transactions. It looks like they just deleted all the data. I guess our GC code accidentally matched everything.
|
|
231
|
+
// Ah, but... We know the files that were deleted, and they're just moved to the recycle bin. So we should just really go from the transactions to find all of the old values.
|
|
232
|
+
// AND... somehow we deleted everything, all transactions, everything.
|
|
233
|
+
// - Must have been during the attempt to restore it.
|
|
234
|
+
// let files = await archivesRecycleBin().findInfo("");
|
|
235
|
+
// console.log(files);
|
|
236
|
+
// console.log(files.length);
|
|
237
|
+
// require("debugbreak")(2);
|
|
238
|
+
// debugger;
|
|
239
|
+
|
|
240
|
+
// let snapshot = await pathValueArchives.loadValues({
|
|
241
|
+
// type: "remaining",
|
|
242
|
+
// excludedPrefixes: [],
|
|
243
|
+
// });
|
|
244
|
+
// let allValues = Object.values(snapshot.values).flat();
|
|
245
|
+
// console.log(`Total values loaded: ${formatNumber(allValues.length)}`);
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
// let transactionRaw = await archivesRecycleBin().get(badDeleteTransaction);
|
|
249
|
+
// if (!transactionRaw) throw new Error(`Transaction not found: ${badDeleteTransaction}`);
|
|
250
|
+
// console.log(transactionRaw?.toString());
|
|
251
|
+
|
|
252
|
+
// let transaction = JSON.parse(transactionRaw.toString()) as Transaction;
|
|
253
|
+
// let files = transaction.ops.filter(a => a.type === "delete").map(a => a.key);
|
|
254
|
+
// await saveSnapshot({ files });
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
// await Querysub.hostService("test");
|
|
260
|
+
// //let topology = await authorityLookup.getTopology();
|
|
261
|
+
// let parentPath = ".,querysubtest._com.,PathFunctionRunner.,book.,Data.,edittingBooks.,hkwnmoiwhuyqenbi.,books.,";
|
|
262
|
+
// clientWatcher.setWatches({
|
|
263
|
+
// paths: new Set([]),
|
|
264
|
+
// parentPaths: new Set([parentPath]),
|
|
265
|
+
// callback: () => {
|
|
266
|
+
// let value = authorityStorage.getPathsFromParent(parentPath);
|
|
267
|
+
// console.log({ parentPaths: value?.size, isSynced: authorityStorage.isParentSynced(parentPath) });
|
|
268
|
+
// }
|
|
269
|
+
// });
|
|
270
|
+
|
|
271
|
+
// await Querysub.hostService("test");
|
|
272
|
+
|
|
273
|
+
// let snapshot = await pathValueArchives.loadValues({
|
|
274
|
+
// type: "remaining",
|
|
275
|
+
// excludedPrefixes: [],
|
|
276
|
+
// });
|
|
277
|
+
// let allValues = Object.values(snapshot.values).flat();
|
|
278
|
+
// console.log(`Total values loaded: ${formatNumber(allValues.length)}`);
|
|
279
|
+
|
|
280
|
+
// let splitLevel = 4;
|
|
281
|
+
// let paths = new Map<string, {
|
|
282
|
+
// count: number;
|
|
283
|
+
// }>();
|
|
284
|
+
// for (let value of allValues) {
|
|
285
|
+
// let path = value.path;
|
|
286
|
+
// let prefix = trimPathStrToDepth(path, splitLevel);
|
|
287
|
+
// let entry = paths.get(prefix);
|
|
288
|
+
// if (!entry) {
|
|
289
|
+
// entry = { count: 0 };
|
|
290
|
+
// paths.set(prefix, entry);
|
|
291
|
+
// }
|
|
292
|
+
// entry.count++;
|
|
293
|
+
// }
|
|
294
|
+
// // Log the 10 biggest paths
|
|
295
|
+
// let entries = Array.from(paths.entries());
|
|
296
|
+
// sort(entries, x => -x[1].count);
|
|
297
|
+
// for (let [path, entry] of entries.slice(0, 10)) {
|
|
298
|
+
// console.log(`${formatNumber(entry.count)}\t${path}`);
|
|
299
|
+
// }
|
|
109
300
|
}
|
|
110
301
|
|
|
111
|
-
main().catch(console.error)
|
|
302
|
+
main().catch(console.error)
|
|
303
|
+
.finally(() => process.exit(0))
|
|
304
|
+
;
|