@matterbridge/thread 3.10.14-dev-20261009-3757ec0 → 3.10.14-dev-20261012-c6da540
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.
|
@@ -12,6 +12,7 @@ export declare class BroadcastServer extends EventEmitter<BroadcastServerEvents>
|
|
|
12
12
|
private closed;
|
|
13
13
|
private readonly debug;
|
|
14
14
|
private readonly verbose;
|
|
15
|
+
private readonly diagnostic;
|
|
15
16
|
constructor(name: WorkerSrcType, log: AnsiLogger, channel?: string);
|
|
16
17
|
close(): void;
|
|
17
18
|
private broadcastMessageHandler;
|
package/dist/broadcastServer.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import { BroadcastChannel } from 'node:worker_threads';
|
|
3
|
-
import {
|
|
3
|
+
import { hasAnyParameter } from '@matterbridge/utils/cli';
|
|
4
|
+
import { writeDiagnostic } from '@matterbridge/utils/diagnostic';
|
|
4
5
|
import { logError } from '@matterbridge/utils/error';
|
|
5
6
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
6
7
|
import { CYAN, db, debugStringify, er } from 'node-ansi-logger';
|
|
@@ -11,8 +12,9 @@ export class BroadcastServer extends EventEmitter {
|
|
|
11
12
|
channel;
|
|
12
13
|
broadcastChannel;
|
|
13
14
|
closed = false;
|
|
14
|
-
debug =
|
|
15
|
-
verbose =
|
|
15
|
+
debug = hasAnyParameter('debug', 'verbose', 'debug-broadcast', 'verbose-broadcast');
|
|
16
|
+
verbose = hasAnyParameter('verbose', 'verbose-broadcast');
|
|
17
|
+
diagnostic = hasAnyParameter('diagnostic', 'diagnostic-broadcast');
|
|
16
18
|
constructor(name, log, channel = 'broadcast-channel') {
|
|
17
19
|
super();
|
|
18
20
|
this.name = name;
|
|
@@ -158,6 +160,7 @@ export class BroadcastServer extends EventEmitter {
|
|
|
158
160
|
return Promise.reject(new Error('Broadcast channel is closed'));
|
|
159
161
|
}
|
|
160
162
|
let timeoutId;
|
|
163
|
+
const start = performance.now();
|
|
161
164
|
const requestMessage = {
|
|
162
165
|
...message,
|
|
163
166
|
id: message.id ?? this.getUniqueId(),
|
|
@@ -173,6 +176,8 @@ export class BroadcastServer extends EventEmitter {
|
|
|
173
176
|
this.off('broadcast_message', responseHandler);
|
|
174
177
|
if (this.verbose)
|
|
175
178
|
this.log.debug(`Fetch response: ${debugStringify(msg)}`);
|
|
179
|
+
if (this.diagnostic)
|
|
180
|
+
writeDiagnostic(`Broadcast:${this.name}`, `fetch ${requestMessage.type} from ${requestMessage.src} to ${requestMessage.dst} took ${(performance.now() - start).toFixed(2)} ms`);
|
|
176
181
|
if ('error' in msg && typeof msg.error === 'string') {
|
|
177
182
|
reject(new Error(`Fetch received error response ${msg.error} to message type ${requestMessage.type} id ${requestMessage.id} from ${requestMessage.src} to ${requestMessage.dst}`));
|
|
178
183
|
}
|
package/dist/threadsManager.js
CHANGED
|
@@ -27,8 +27,8 @@ export class ThreadsManager {
|
|
|
27
27
|
{ name: 'SpawnCommand', path: 'workerSpawnCommand.js', type: 'worker' },
|
|
28
28
|
{ name: 'ArchiveCommand', path: 'workerArchiveCommand.js', type: 'worker' },
|
|
29
29
|
{ name: 'DockerVersion', path: 'workerDockerVersion.js', type: 'worker' },
|
|
30
|
-
{ name: 'Backend', path: 'threadBackend.js', type: 'thread' },
|
|
31
|
-
{ name: 'RootNode', path: 'threadRootNode.js', type: 'thread', multiple: true },
|
|
30
|
+
{ name: 'Backend', path: 'threadBackend.js', type: 'thread', startup: true, shutdown: true },
|
|
31
|
+
{ name: 'RootNode', path: 'threadRootNode.js', type: 'thread', multiple: true, startup: true, shutdown: true },
|
|
32
32
|
{ name: 'Tracker', path: 'threadTracker.js', type: 'thread', multiple: true, startup: true, shutdown: true },
|
|
33
33
|
];
|
|
34
34
|
terminateWorkers = new Set();
|
|
@@ -62,7 +62,7 @@ export class ThreadsManager {
|
|
|
62
62
|
this.log.notice(`ThreadsManager destroyed. Broadcast server closed.`);
|
|
63
63
|
}
|
|
64
64
|
msgHandler(msg) {
|
|
65
|
-
if (this.server.isWorkerRequest(msg)
|
|
65
|
+
if (this.server.isWorkerRequest(msg)) {
|
|
66
66
|
if (this.verbose)
|
|
67
67
|
this.log.debug(`Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
68
68
|
switch (msg.type) {
|
|
@@ -141,12 +141,13 @@ export class ThreadsManager {
|
|
|
141
141
|
this.terminateExitedWorkers();
|
|
142
142
|
for (const thread of this.threads) {
|
|
143
143
|
for (const info of [thread, ...(thread.instances ?? [])]) {
|
|
144
|
-
if (info.worker
|
|
144
|
+
if (info.worker) {
|
|
145
145
|
const msg = { type: 'ping', threadId: info.worker.threadId, threadName: thread.name };
|
|
146
146
|
info.worker.postMessage(msg);
|
|
147
|
+
this.log.debug(`Sent ping to thread ${thread.name} threadId ${info.worker.threadId}`);
|
|
147
148
|
}
|
|
148
149
|
if (info.worker && Date.now() - (info.lastSeen ?? 0) > this.intervalMs * 2) {
|
|
149
|
-
this.log.warn(`Thread ${CYAN}${thread.name}${
|
|
150
|
+
this.log.warn(`Thread ${CYAN}${thread.name}${wr} has not been seen for more than ${this.intervalMs * 2} ms. It may be unresponsive.`);
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
}
|
|
@@ -205,7 +206,10 @@ export class ThreadsManager {
|
|
|
205
206
|
this.log.debug(`Thread ${threadInfo.name} sent a message at ${new Date(now).toISOString()}: ${debugStringify(message)}`);
|
|
206
207
|
if (message.type === 'init') {
|
|
207
208
|
threadInfo.runCount = (threadInfo.runCount ?? 0) + 1;
|
|
208
|
-
this.log.debug(`Thread ${threadInfo.name} is
|
|
209
|
+
this.log.debug(`Thread ${threadInfo.name} is initialized at ${new Date(now).toISOString()} with thread id ${worker.threadId}`);
|
|
210
|
+
}
|
|
211
|
+
else if (message.type === 'ready') {
|
|
212
|
+
this.log.debug(`Thread ${threadInfo.name} is ready at ${new Date(now).toISOString()} with thread id ${worker.threadId}`);
|
|
209
213
|
if (threadInfo.startup) {
|
|
210
214
|
const startupMessage = { type: 'startup', threadName: threadInfo.name, threadId: worker.threadId };
|
|
211
215
|
worker.postMessage(startupMessage);
|
package/dist/threadsWrapper.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export interface ThreadsWrapperEvents {
|
|
|
10
10
|
export declare class ThreadsWrapper extends EventEmitter<ThreadsWrapperEvents> {
|
|
11
11
|
name: ThreadNames;
|
|
12
12
|
entrypoint: (worker: ThreadsWrapper) => Promise<boolean>;
|
|
13
|
+
startup?: ((worker: ThreadsWrapper) => Promise<void>) | undefined;
|
|
14
|
+
shutdown?: ((worker: ThreadsWrapper) => Promise<void>) | undefined;
|
|
13
15
|
debug: boolean;
|
|
14
16
|
verbose: boolean;
|
|
15
17
|
useTracker: boolean;
|
|
@@ -20,7 +22,7 @@ export declare class ThreadsWrapper extends EventEmitter<ThreadsWrapperEvents> {
|
|
|
20
22
|
private destroyed;
|
|
21
23
|
private readonly boundUnhandledRejectionHandler;
|
|
22
24
|
private readonly boundUncaughtExceptionHandler;
|
|
23
|
-
constructor(name: ThreadNames, entrypoint: (worker: ThreadsWrapper) => Promise<boolean>);
|
|
25
|
+
constructor(name: ThreadNames, entrypoint: (worker: ThreadsWrapper) => Promise<boolean>, startup?: ((worker: ThreadsWrapper) => Promise<void>) | undefined, shutdown?: ((worker: ThreadsWrapper) => Promise<void>) | undefined);
|
|
24
26
|
destroy(success: boolean): void;
|
|
25
27
|
private handleUnhandledRejection;
|
|
26
28
|
private handleUncaughtException;
|
package/dist/threadsWrapper.js
CHANGED
|
@@ -11,6 +11,8 @@ logModuleLoaded('ThreadsWrapper');
|
|
|
11
11
|
export class ThreadsWrapper extends EventEmitter {
|
|
12
12
|
name;
|
|
13
13
|
entrypoint;
|
|
14
|
+
startup;
|
|
15
|
+
shutdown;
|
|
14
16
|
debug = hasAnyParameter('debug', 'verbose', 'debug-threads', 'verbose-threads');
|
|
15
17
|
verbose = hasAnyParameter('verbose', 'verbose-threads');
|
|
16
18
|
useTracker = hasAnyParameter('tracker', 'tracker-threads');
|
|
@@ -25,10 +27,12 @@ export class ThreadsWrapper extends EventEmitter {
|
|
|
25
27
|
boundUncaughtExceptionHandler = (error) => {
|
|
26
28
|
this.handleUncaughtException(error);
|
|
27
29
|
};
|
|
28
|
-
constructor(name, entrypoint) {
|
|
30
|
+
constructor(name, entrypoint, startup, shutdown) {
|
|
29
31
|
super();
|
|
30
32
|
this.name = name;
|
|
31
33
|
this.entrypoint = entrypoint;
|
|
34
|
+
this.startup = startup;
|
|
35
|
+
this.shutdown = shutdown;
|
|
32
36
|
if (this.workerData) {
|
|
33
37
|
this.debug = this.workerData.debug ?? this.debug;
|
|
34
38
|
this.verbose = this.workerData.verbose ?? this.verbose;
|
|
@@ -43,7 +47,7 @@ export class ThreadsWrapper extends EventEmitter {
|
|
|
43
47
|
if (this.useTracker) {
|
|
44
48
|
void import('@matterbridge/utils/tracker')
|
|
45
49
|
.then(({ Tracker }) => {
|
|
46
|
-
this.tracker = new Tracker(`Thread${this.name}`, this.debug
|
|
50
|
+
this.tracker = new Tracker(`Thread${this.name}`, this.debug, this.verbose, this.useTracker);
|
|
47
51
|
this.tracker.start();
|
|
48
52
|
return;
|
|
49
53
|
})
|
|
@@ -68,10 +72,32 @@ export class ThreadsWrapper extends EventEmitter {
|
|
|
68
72
|
this.parentLog(this.name, "debug", `Worker ${this.name}:${threadId} sent pong message type to parent: ${debugStringify(message)}`);
|
|
69
73
|
break;
|
|
70
74
|
case 'startup':
|
|
71
|
-
setImmediate(() =>
|
|
75
|
+
setImmediate(() => {
|
|
76
|
+
void (async () => {
|
|
77
|
+
try {
|
|
78
|
+
if (startup)
|
|
79
|
+
await startup(this);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
inspectError(this.log, `Worker ${this.name} startup failed`, err);
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
this.emit('startup');
|
|
86
|
+
});
|
|
72
87
|
break;
|
|
73
88
|
case 'shutdown':
|
|
74
|
-
setImmediate(() =>
|
|
89
|
+
setImmediate(() => {
|
|
90
|
+
void (async () => {
|
|
91
|
+
try {
|
|
92
|
+
if (shutdown)
|
|
93
|
+
await shutdown(this);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
inspectError(this.log, `Worker ${this.name} shutdown failed`, err);
|
|
97
|
+
}
|
|
98
|
+
})();
|
|
99
|
+
this.emit('shutdown');
|
|
100
|
+
});
|
|
75
101
|
break;
|
|
76
102
|
default:
|
|
77
103
|
this.parentLog(this.name, "warn", `Worker ${this.name}:${threadId} received unknown message type from parent: ${debugStringify(message)}`);
|
|
@@ -95,6 +121,7 @@ export class ThreadsWrapper extends EventEmitter {
|
|
|
95
121
|
let success = false;
|
|
96
122
|
try {
|
|
97
123
|
success = await entrypoint(this);
|
|
124
|
+
this.parentPost({ type: 'ready', threadId, threadName: this.name, memoryUsage: process.memoryUsage(), success: true });
|
|
98
125
|
}
|
|
99
126
|
catch (err) {
|
|
100
127
|
inspectError(this.log, `Worker ${this.name} entrypoint failed`, err);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/thread",
|
|
3
|
-
"version": "3.10.14-dev-
|
|
3
|
+
"version": "3.10.14-dev-20261012-c6da540",
|
|
4
4
|
"description": "Matterbridge thread library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@matter/main": "0.17.9",
|
|
83
|
-
"@matterbridge/types": "3.10.14-dev-
|
|
84
|
-
"@matterbridge/utils": "3.10.14-dev-
|
|
83
|
+
"@matterbridge/types": "3.10.14-dev-20261012-c6da540",
|
|
84
|
+
"@matterbridge/utils": "3.10.14-dev-20261012-c6da540",
|
|
85
85
|
"@zip.js/zip.js": "2.23.0",
|
|
86
86
|
"node-ansi-logger": "3.3.1"
|
|
87
87
|
}
|