@matterbridge/thread 3.9.3-dev-20260629-7c47082 → 3.9.3-dev-20260630-9b4b673
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/checkUpdates.d.ts +2 -2
- package/dist/checkUpdates.js +10 -15
- package/dist/spawnCommand.js +1 -0
- package/dist/threadsManager.d.ts +2 -0
- package/dist/threadsManager.js +23 -0
- package/dist/workerCheckUpdates.js +1 -1
- package/dist/workerWrapper.js +1 -1
- package/package.json +3 -3
package/dist/checkUpdates.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ApiPlugin, SharedMatterbridge } from '@matterbridge/types';
|
|
2
2
|
import { AnsiLogger } from 'node-ansi-logger';
|
|
3
|
-
import { BroadcastServer } from './broadcastServer.js';
|
|
4
|
-
export declare function checkUpdates(matterbridge: SharedMatterbridge): Promise<void>;
|
|
3
|
+
import type { BroadcastServer } from './broadcastServer.js';
|
|
4
|
+
export declare function checkUpdates(matterbridge: SharedMatterbridge, server: BroadcastServer): Promise<void>;
|
|
5
5
|
export declare function checkUpdatesAndLog(matterbridge: SharedMatterbridge, log: AnsiLogger, server: BroadcastServer): Promise<void>;
|
|
6
6
|
export declare function getMatterbridgeLatestVersion(matterbridge: SharedMatterbridge, log: AnsiLogger, server: BroadcastServer): Promise<string | undefined>;
|
|
7
7
|
export declare function getMatterbridgeDevVersion(matterbridge: SharedMatterbridge, log: AnsiLogger, server: BroadcastServer): Promise<string | undefined>;
|
package/dist/checkUpdates.js
CHANGED
|
@@ -4,33 +4,28 @@ import { getErrorMessage } from '@matterbridge/utils/error';
|
|
|
4
4
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
5
5
|
import { isValidString } from '@matterbridge/utils/validate';
|
|
6
6
|
import { AnsiLogger, db, debugStringify, nt, wr } from 'node-ansi-logger';
|
|
7
|
-
import { BroadcastServer } from './broadcastServer.js';
|
|
8
7
|
logModuleLoaded('CheckUpdates');
|
|
9
8
|
let noUpdatesAvailable = true;
|
|
10
|
-
export async function checkUpdates(matterbridge) {
|
|
9
|
+
export async function checkUpdates(matterbridge, server) {
|
|
11
10
|
const log = new AnsiLogger({ logName: 'MatterbridgeUpdates', logTimestampFormat: 4, logLevel: matterbridge.logLevel });
|
|
12
|
-
const server = new BroadcastServer('updates', log);
|
|
13
11
|
noUpdatesAvailable = true;
|
|
14
|
-
|
|
15
|
-
const latestVersionPromise = getMatterbridgeLatestVersion(matterbridge, log, server);
|
|
16
|
-
const devVersionPromise = getMatterbridgeDevVersion(matterbridge, log, server);
|
|
17
|
-
const pluginsVersionPromises = [];
|
|
18
|
-
const pluginsDevVersionPromises = [];
|
|
12
|
+
let plugins = [];
|
|
19
13
|
try {
|
|
20
|
-
|
|
21
|
-
for (const plugin of plugins) {
|
|
22
|
-
pluginsVersionPromises.push(getPluginLatestVersion(log, server, plugin));
|
|
23
|
-
pluginsDevVersionPromises.push(getPluginDevVersion(log, server, plugin));
|
|
24
|
-
}
|
|
14
|
+
plugins = (await server.fetch({ type: 'plugins_apipluginarray', src: server.name, dst: 'plugins' }, 1000)).result.plugins;
|
|
25
15
|
}
|
|
26
16
|
catch (error) {
|
|
27
17
|
log.debug(`Error fetching plugins for update check: ${getErrorMessage(error)}`);
|
|
28
18
|
}
|
|
29
|
-
await
|
|
19
|
+
await checkUpdatesAndLog(matterbridge, log, server);
|
|
20
|
+
await getMatterbridgeLatestVersion(matterbridge, log, server);
|
|
21
|
+
await getMatterbridgeDevVersion(matterbridge, log, server);
|
|
22
|
+
for (const plugin of plugins) {
|
|
23
|
+
await getPluginLatestVersion(log, server, plugin);
|
|
24
|
+
await getPluginDevVersion(log, server, plugin);
|
|
25
|
+
}
|
|
30
26
|
if (noUpdatesAvailable) {
|
|
31
27
|
server.request({ type: 'frontend_snackbarmessage', src: server.name, dst: 'frontend', params: { message: 'No updates available', timeout: 5, severity: 'info' } });
|
|
32
28
|
}
|
|
33
|
-
server.close();
|
|
34
29
|
}
|
|
35
30
|
export async function checkUpdatesAndLog(matterbridge, log, server) {
|
|
36
31
|
const { getGitHubUpdate } = await import('@matterbridge/utils/github-version');
|
package/dist/spawnCommand.js
CHANGED
|
@@ -32,6 +32,7 @@ export async function spawnCommand(command, args, packageCommand, packageName) {
|
|
|
32
32
|
(command === 'npm' || command === 'bun') &&
|
|
33
33
|
!hasParameter('docker') &&
|
|
34
34
|
!hasParameter('nosudo') &&
|
|
35
|
+
!isBun() &&
|
|
35
36
|
!process.env.PATH?.includes('/.nvm/versions/node/'))) {
|
|
36
37
|
args.unshift(command === 'npm' && isBun() ? 'bun' : command);
|
|
37
38
|
command = 'sudo';
|
package/dist/threadsManager.d.ts
CHANGED
|
@@ -12,9 +12,11 @@ export declare class ThreadsManager {
|
|
|
12
12
|
private interval;
|
|
13
13
|
private intervalMs;
|
|
14
14
|
private threads;
|
|
15
|
+
private terminateWorkers;
|
|
15
16
|
constructor(intervalMs?: number);
|
|
16
17
|
destroy(): void;
|
|
17
18
|
private msgHandler;
|
|
19
|
+
private terminateExitedWorkers;
|
|
18
20
|
private intervalHandler;
|
|
19
21
|
runThread(name: string, workerData?: WorkerData, argv?: string[], env?: NodeJS.ProcessEnv, execArgv?: string[], pipedOutput?: boolean): Worker;
|
|
20
22
|
runInMainThread(name: string, workerData?: WorkerData | null): Promise<boolean>;
|
package/dist/threadsManager.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Worker } from 'node:worker_threads';
|
|
|
5
5
|
import { hasParameter } from '@matterbridge/utils/cli';
|
|
6
6
|
import { getErrorMessage } from '@matterbridge/utils/error';
|
|
7
7
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
8
|
+
import { fireAndForget } from '@matterbridge/utils/wait';
|
|
8
9
|
import { AnsiLogger, CYAN, db, debugStringify, ft, MAGENTA, wr } from 'node-ansi-logger';
|
|
9
10
|
import { BroadcastServer } from './broadcastServer.js';
|
|
10
11
|
logModuleLoaded('ThreadsManager');
|
|
@@ -26,6 +27,7 @@ export class ThreadsManager {
|
|
|
26
27
|
{ name: 'ArchiveCommand', path: 'workerArchiveCommand.js', type: 'worker' },
|
|
27
28
|
{ name: 'DockerVersion', path: 'workerDockerVersion.js', type: 'worker' },
|
|
28
29
|
];
|
|
30
|
+
terminateWorkers = new Set();
|
|
29
31
|
constructor(intervalMs = 60_000) {
|
|
30
32
|
this.debug = hasParameter('debug') || hasParameter('verbose') || hasParameter('debug-threads') || hasParameter('verbose-threads');
|
|
31
33
|
this.verbose = hasParameter('verbose') || hasParameter('verbose-threads');
|
|
@@ -47,6 +49,7 @@ export class ThreadsManager {
|
|
|
47
49
|
}
|
|
48
50
|
destroy() {
|
|
49
51
|
clearInterval(this.interval);
|
|
52
|
+
this.terminateExitedWorkers();
|
|
50
53
|
this.server.off('broadcast_message', this.boundMsgHandler);
|
|
51
54
|
this.server.close();
|
|
52
55
|
if (this.verbose)
|
|
@@ -83,10 +86,26 @@ export class ThreadsManager {
|
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
88
|
}
|
|
89
|
+
terminateExitedWorkers() {
|
|
90
|
+
if (this.terminateWorkers.size > 0) {
|
|
91
|
+
this.log.debug(`Terminating ${this.terminateWorkers.size} workers that have exited...`);
|
|
92
|
+
for (const worker of this.terminateWorkers) {
|
|
93
|
+
try {
|
|
94
|
+
this.log.debug(`Terminating worker with thread id ${worker.threadId}...`);
|
|
95
|
+
fireAndForget(worker.terminate(), this.log, `Failed to terminate worker with thread id ${worker.threadId}`);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
this.log.error(`Failed to terminate worker with thread id ${worker.threadId}: ${getErrorMessage(error)}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
this.terminateWorkers.clear();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
86
104
|
intervalHandler() {
|
|
87
105
|
for (const thread of this.threads) {
|
|
88
106
|
this.log.debug(`Thread ${thread.name} running: ${thread.worker ? 'yes' : 'no'}, lastSeen: ${thread.lastSeen ? new Date(thread.lastSeen).toISOString() : 'never'}, runs: ${thread.runCount ?? 0}, errors: ${thread.errorCount ?? 0}`);
|
|
89
107
|
}
|
|
108
|
+
this.terminateExitedWorkers();
|
|
90
109
|
for (const thread of this.threads) {
|
|
91
110
|
if (thread.worker && Date.now() - (thread.lastSeen ?? 0) > this.intervalMs) {
|
|
92
111
|
const msg = { type: 'ping', threadId: thread.worker.threadId, threadName: thread.name };
|
|
@@ -128,6 +147,7 @@ export class ThreadsManager {
|
|
|
128
147
|
threadInfo.worker = undefined;
|
|
129
148
|
}
|
|
130
149
|
this.log.debug(`Thread ${threadInfo.name} has exited at ${new Date(now).toISOString()}`);
|
|
150
|
+
this.terminateWorkers.delete(worker);
|
|
131
151
|
});
|
|
132
152
|
worker.on('message', (message) => {
|
|
133
153
|
const now = Date.now();
|
|
@@ -148,6 +168,7 @@ export class ThreadsManager {
|
|
|
148
168
|
if (!message.success) {
|
|
149
169
|
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
150
170
|
}
|
|
171
|
+
this.terminateWorkers.add(worker);
|
|
151
172
|
threadInfo.worker = undefined;
|
|
152
173
|
this.log.debug(`Thread ${threadInfo.name} has exited at ${new Date(now).toISOString()} with thread id ${worker.threadId} after running for ${threadInfo.lastDuration} ms`);
|
|
153
174
|
}
|
|
@@ -165,6 +186,7 @@ export class ThreadsManager {
|
|
|
165
186
|
threadInfo.lastDuration = Math.max(0, now - (threadInfo.lastStarted ?? now));
|
|
166
187
|
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
167
188
|
threadInfo.worker = undefined;
|
|
189
|
+
this.terminateWorkers.add(worker);
|
|
168
190
|
this.log.error(`Thread ${threadInfo.name} encountered an error at ${new Date(now).toISOString()} after running for ${threadInfo.lastDuration} ms: ${getErrorMessage(error)}`);
|
|
169
191
|
});
|
|
170
192
|
this.log.debug(`Started thread ${threadInfo.name} from path ${path} type ${threadInfo.type} with thread id ${worker.threadId}`);
|
|
@@ -191,6 +213,7 @@ export class ThreadsManager {
|
|
|
191
213
|
const candidates = [
|
|
192
214
|
path.join(currentModuleDirectory, fileName),
|
|
193
215
|
path.join(currentModuleDirectory, '..', 'dist', fileName),
|
|
216
|
+
path.join(currentModuleDirectory, '..', 'src', fileName.replace(/\.js$/, '.ts')),
|
|
194
217
|
path.join(currentModuleDirectory, 'workers', fileName),
|
|
195
218
|
];
|
|
196
219
|
for (const candidate of candidates) {
|
|
@@ -8,7 +8,7 @@ export default new WorkerWrapper('CheckUpdates', async (worker) => {
|
|
|
8
8
|
let success = false;
|
|
9
9
|
try {
|
|
10
10
|
const shared = (await worker.server.fetch({ type: 'matterbridge_shared', src: `matterbridge`, dst: 'matterbridge' }, 5000)).result.data;
|
|
11
|
-
await checkUpdates(shared);
|
|
11
|
+
await checkUpdates(shared, worker.server);
|
|
12
12
|
worker.logger("info", `Check updates succeeded`);
|
|
13
13
|
success = true;
|
|
14
14
|
}
|
package/dist/workerWrapper.js
CHANGED
|
@@ -124,7 +124,6 @@ export class WorkerWrapper {
|
|
|
124
124
|
}
|
|
125
125
|
try {
|
|
126
126
|
parentPort.close();
|
|
127
|
-
process.exit(success ? 0 : 1);
|
|
128
127
|
}
|
|
129
128
|
catch (error) {
|
|
130
129
|
this.log.error(`Worker ${this.name}:${threadId} failed to close parentPort: ${getErrorMessage(error)}`);
|
|
@@ -146,6 +145,7 @@ export class WorkerWrapper {
|
|
|
146
145
|
this.destroy(false);
|
|
147
146
|
}
|
|
148
147
|
safeParentLog(level, message) {
|
|
148
|
+
this.log.error(`Worker ${this.name}: ${message}`);
|
|
149
149
|
if (this.destroyed)
|
|
150
150
|
return;
|
|
151
151
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/thread",
|
|
3
|
-
"version": "3.9.3-dev-
|
|
3
|
+
"version": "3.9.3-dev-20260630-9b4b673",
|
|
4
4
|
"description": "Matterbridge thread library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"CHANGELOG.md"
|
|
70
70
|
],
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@matterbridge/types": "3.9.3-dev-
|
|
73
|
-
"@matterbridge/utils": "3.9.3-dev-
|
|
72
|
+
"@matterbridge/types": "3.9.3-dev-20260630-9b4b673",
|
|
73
|
+
"@matterbridge/utils": "3.9.3-dev-20260630-9b4b673",
|
|
74
74
|
"@zip.js/zip.js": "2.8.26",
|
|
75
75
|
"node-ansi-logger": "3.3.0"
|
|
76
76
|
}
|