@spirobel/monero-wallet-api 0.5.4 → 0.5.5
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/dist/io/sleep.d.ts +1 -1
- package/dist/io/sleep.js +16 -1
- package/dist/scanning-syncing/backgroundWorker.d.ts +2 -0
- package/dist/scanning-syncing/backgroundWorker.js +92 -10
- package/dist/scanning-syncing/blocksbuffer/blocksBufferFetchLoop.js +33 -2
- package/dist/scanning-syncing/connectionStatus.d.ts +6 -0
- package/dist/scanning-syncing/connectionStatus.js +15 -0
- package/dist/scanning-syncing/connectionStatusOpened.d.ts +2 -0
- package/dist/scanning-syncing/connectionStatusOpened.js +20 -3
- package/dist/scanning-syncing/openWallet.d.ts +4 -1
- package/dist/scanning-syncing/openWallet.js +3 -0
- package/dist/scanning-syncing/scanresult/scanCacheOpened.d.ts +10 -4
- package/dist/scanning-syncing/scanresult/scanCacheOpened.js +117 -56
- package/dist/scanning-syncing/scanresult/scanCoordination.d.ts +6 -3
- package/dist/scanning-syncing/scanresult/scanCoordination.js +87 -25
- package/dist/scanning-syncing/scanresult/scanLoop.d.ts +1 -2
- package/dist/scanning-syncing/scanresult/scanLoop.js +0 -13
- package/dist/scanning-syncing/worker-entrypoints/worker.js +1 -1
- package/dist/scanning-syncing/worker-mains/coordinator-main.d.ts +1 -0
- package/dist/scanning-syncing/worker-mains/coordinator-main.js +16 -1
- package/dist/scanning-syncing/worker-mains/cpubound-main.js +3 -2
- package/dist/scanning-syncing/worker-mains/worker.js +45 -2
- package/package.json +1 -1
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { coordinatorMainMultithreaded } from "../scanresult/scanCoordination";
|
|
2
2
|
import { log } from "../../io/logging";
|
|
3
|
+
// one controller per coordinator worker; shutdown aborts fetch + race
|
|
4
|
+
let shutdownController;
|
|
5
|
+
export function requestCoordinatorShutdown() {
|
|
6
|
+
log("coordinatorMainWorker", ["shutdown requested"]);
|
|
7
|
+
shutdownController?.abort();
|
|
8
|
+
}
|
|
3
9
|
export async function coordinatorMainWorker(scan_settings_path, pathPrefix, cpuPorts) {
|
|
4
10
|
log("coordinatorMainWorker", "cpuPorts=" + cpuPorts?.length);
|
|
11
|
+
shutdownController = new AbortController();
|
|
5
12
|
try {
|
|
6
|
-
const gen = coordinatorMainMultithreaded(scan_settings_path, pathPrefix, cpuPorts);
|
|
13
|
+
const gen = coordinatorMainMultithreaded(scan_settings_path, pathPrefix, cpuPorts, shutdownController.signal);
|
|
7
14
|
for await (const event of gen) {
|
|
8
15
|
log("coordinatorMainWorker", ["event:", event]);
|
|
9
16
|
if (event.type === "scan_ready") {
|
|
@@ -15,9 +22,17 @@ export async function coordinatorMainWorker(scan_settings_path, pathPrefix, cpuP
|
|
|
15
22
|
},
|
|
16
23
|
});
|
|
17
24
|
}
|
|
25
|
+
else if (event.type === "shutdown_done") {
|
|
26
|
+
self.postMessage({ type: "SHUTDOWN_DONE" });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
18
29
|
}
|
|
30
|
+
// generator returned without shutdown_done (e.g. empty)
|
|
31
|
+
self.postMessage({ type: "SHUTDOWN_DONE" });
|
|
19
32
|
}
|
|
20
33
|
catch (error) {
|
|
34
|
+
// still tell main thread we stopped so terminate can proceed
|
|
35
|
+
self.postMessage({ type: "SHUTDOWN_DONE" });
|
|
21
36
|
self.postMessage({ type: "ERROR", payload: error });
|
|
22
37
|
}
|
|
23
38
|
}
|
|
@@ -14,8 +14,9 @@ export async function handleCpuboundScan(msg, cpu_worker_status) {
|
|
|
14
14
|
throw new Error("[cpubound] no content msg! ( ScanLoopInput = undefined )");
|
|
15
15
|
}
|
|
16
16
|
if (msg === "cancel") {
|
|
17
|
+
// idle cancel: nothing in flight, just ack
|
|
17
18
|
log("handleCpuboundScan", "cancel msg! ( ScanLoopInput = cancel )");
|
|
18
|
-
|
|
19
|
+
return { type: "Canceled" };
|
|
19
20
|
}
|
|
20
21
|
log("handleCpuboundScan", "got scan msg, walletConfig=" +
|
|
21
22
|
msg.walletConfig?.primary_address?.slice(0, 6));
|
|
@@ -89,7 +90,7 @@ export async function handleCpuboundScan(msg, cpu_worker_status) {
|
|
|
89
90
|
if (cpu_worker_status.cancel) {
|
|
90
91
|
cpu_worker_status.cancel = false;
|
|
91
92
|
log("handleCpuboundScan", ["cpu work canceled"]);
|
|
92
|
-
return { type: "
|
|
93
|
+
return { type: "Canceled", work_uuid: item.work_uuid };
|
|
93
94
|
}
|
|
94
95
|
await sleep(10); // make sure the loop is not tight
|
|
95
96
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { coordinatorMainWorker } from "./coordinator-main";
|
|
1
|
+
import { coordinatorMainWorker, requestCoordinatorShutdown, } from "./coordinator-main";
|
|
2
2
|
import { handleCpuboundScanTry, sendFromCpuWorker } from "./cpubound-main";
|
|
3
3
|
import { log, setupLoggingPath } from "../../io/logging";
|
|
4
4
|
import { multisigMainWorkerCall } from "./multisig-main";
|
|
@@ -9,21 +9,32 @@ let SCAN_SETTINGS_PATH;
|
|
|
9
9
|
let PATH_PREFIX;
|
|
10
10
|
let cpuPort;
|
|
11
11
|
const cpu_worker_status = { cancel: false };
|
|
12
|
+
// true while a scan is running so idle cancel can ack immediately
|
|
13
|
+
let cpu_work_in_flight = false;
|
|
12
14
|
let multisig_dkg;
|
|
13
15
|
export function CPU_PORT_HANDLER(pe) {
|
|
14
16
|
if (pe.data === "cancel") {
|
|
15
|
-
|
|
17
|
+
if (cpu_work_in_flight) {
|
|
18
|
+
cpu_worker_status.cancel = true;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// idle cancel: ack right away so coordinator drain does not hang
|
|
22
|
+
if (cpuPort) {
|
|
23
|
+
sendFromCpuWorker(cpuPort, { type: "Canceled" });
|
|
24
|
+
}
|
|
16
25
|
return;
|
|
17
26
|
}
|
|
18
27
|
if (!cpuPort)
|
|
19
28
|
throw new Error("[cpubound] cpuPort is undefined in port.onmessage");
|
|
20
29
|
log("CPU_PORT_HANDLER", "new workitem msg received");
|
|
30
|
+
cpu_work_in_flight = true;
|
|
21
31
|
cpuPort.postMessage({
|
|
22
32
|
type: "WORKSTART",
|
|
23
33
|
work_uuid: pe.data.work_uuid,
|
|
24
34
|
});
|
|
25
35
|
handleCpuboundScanTry(pe.data, cpu_worker_status).then((result) => {
|
|
26
36
|
log("CPU_PORT_HANDLER", "work finished, sending result");
|
|
37
|
+
cpu_work_in_flight = false;
|
|
27
38
|
if (!cpuPort)
|
|
28
39
|
throw new Error("[cpubound] cpuPort is undefined in port.onmessage");
|
|
29
40
|
cpuPort.onmessage = CPU_PORT_HANDLER;
|
|
@@ -33,6 +44,38 @@ export function CPU_PORT_HANDLER(pe) {
|
|
|
33
44
|
const handleMessage = async (e) => {
|
|
34
45
|
const msg = e.data;
|
|
35
46
|
log("handleMessage", ["msg received", msg]);
|
|
47
|
+
if (msg.type === "shutdown") {
|
|
48
|
+
// only coordinator listens for this; abort fetch + race loop
|
|
49
|
+
requestCoordinatorShutdown();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (msg.type === "heap_snapshot") {
|
|
53
|
+
try {
|
|
54
|
+
const path = typeof msg.path === "string" && msg.path.length > 0
|
|
55
|
+
? msg.path
|
|
56
|
+
: `worker-heap-${Date.now()}.heapsnapshot`;
|
|
57
|
+
// @ts-ignore bun has generateHeapSnapshot; node has v8.writeHeapSnapshot
|
|
58
|
+
let out;
|
|
59
|
+
if (typeof Bun !== "undefined" && typeof Bun.generateHeapSnapshot === "function") {
|
|
60
|
+
const snap = Bun.generateHeapSnapshot("v8");
|
|
61
|
+
await Bun.write(path, typeof snap === "string" ? snap : JSON.stringify(snap));
|
|
62
|
+
out = path;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
throw Error("in the browser use the inspector directly to observe worker memory growth");
|
|
66
|
+
// const v8 = await import("node:v8");
|
|
67
|
+
// out = v8.writeHeapSnapshot(path);
|
|
68
|
+
}
|
|
69
|
+
self.postMessage({ type: "HEAP_SNAPSHOT_DONE", path: out ?? path });
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
self.postMessage({
|
|
73
|
+
type: "HEAP_SNAPSHOT_ERROR",
|
|
74
|
+
error: err instanceof Error ? err.message : String(err),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
36
79
|
if (msg.type === "setup") {
|
|
37
80
|
const settingsPath = msg.scan_settings_path || SCAN_SETTINGS_STORE_NAME_DEFAULT;
|
|
38
81
|
SCAN_SETTINGS_PATH = settingsPath;
|