@matterbridge/thread 3.9.3-dev-20260628-8ac730c → 3.9.3-dev-20260629-7c47082
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/dockerVersion.js +13 -27
- package/dist/threadsManager.js +6 -2
- package/dist/workerWrapper.d.ts +6 -0
- package/dist/workerWrapper.js +51 -2
- package/package.json +3 -3
package/dist/dockerVersion.js
CHANGED
|
@@ -11,36 +11,18 @@ export function takeDockerVersionWarning() {
|
|
|
11
11
|
async function httpsGetJson(url, headers, timeoutMs) {
|
|
12
12
|
const https = await import('node:https');
|
|
13
13
|
return new Promise((resolve, reject) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (settled)
|
|
19
|
-
return;
|
|
20
|
-
settled = true;
|
|
21
|
-
clearTimeout(timeoutId);
|
|
22
|
-
reject(error);
|
|
23
|
-
};
|
|
24
|
-
const resolveOnce = (value) => {
|
|
25
|
-
if (settled)
|
|
26
|
-
return;
|
|
27
|
-
settled = true;
|
|
28
|
-
clearTimeout(timeoutId);
|
|
29
|
-
resolve(value);
|
|
30
|
-
};
|
|
31
|
-
const timeoutError = new Error(`Request timed out after ${timeoutMs / 1000} seconds`);
|
|
32
|
-
timeoutId = setTimeout(() => {
|
|
33
|
-
req?.destroy?.(timeoutError);
|
|
34
|
-
rejectOnce(timeoutError);
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
const timeoutId = setTimeout(() => {
|
|
16
|
+
controller.abort();
|
|
17
|
+
reject(new Error(`Request timed out after ${timeoutMs / 1000} seconds`));
|
|
35
18
|
}, timeoutMs).unref();
|
|
36
|
-
req = https.get(url, { headers }, (res) => {
|
|
19
|
+
const req = https.get(url, { headers, signal: controller.signal }, (res) => {
|
|
37
20
|
let data = '';
|
|
38
21
|
const statusCode = res.statusCode ?? 0;
|
|
39
22
|
if (statusCode >= 300 && statusCode < 400) {
|
|
40
23
|
const locationHeader = Array.isArray(res.headers.location) ? res.headers.location[0] : res.headers.location;
|
|
41
24
|
if (locationHeader) {
|
|
42
25
|
clearTimeout(timeoutId);
|
|
43
|
-
settled = true;
|
|
44
26
|
res.resume();
|
|
45
27
|
const redirectedUrl = new URL(locationHeader, url).toString();
|
|
46
28
|
let redirectedHeaders = headers;
|
|
@@ -59,8 +41,9 @@ async function httpsGetJson(url, headers, timeoutMs) {
|
|
|
59
41
|
}
|
|
60
42
|
}
|
|
61
43
|
if (statusCode < 200 || statusCode >= 300) {
|
|
44
|
+
clearTimeout(timeoutId);
|
|
62
45
|
res.resume();
|
|
63
|
-
|
|
46
|
+
reject(new Error(`Failed to fetch data. Status code: ${statusCode}`));
|
|
64
47
|
return;
|
|
65
48
|
}
|
|
66
49
|
res.on('data', (chunk) => {
|
|
@@ -68,15 +51,18 @@ async function httpsGetJson(url, headers, timeoutMs) {
|
|
|
68
51
|
});
|
|
69
52
|
res.on('end', () => {
|
|
70
53
|
try {
|
|
71
|
-
|
|
54
|
+
clearTimeout(timeoutId);
|
|
55
|
+
resolve(JSON.parse(data));
|
|
72
56
|
}
|
|
73
57
|
catch (error) {
|
|
74
|
-
|
|
58
|
+
clearTimeout(timeoutId);
|
|
59
|
+
reject(new Error(`Failed to parse response JSON: ${getErrorMessage(error)}`));
|
|
75
60
|
}
|
|
76
61
|
});
|
|
77
62
|
});
|
|
78
63
|
req.on('error', (error) => {
|
|
79
|
-
|
|
64
|
+
clearTimeout(timeoutId);
|
|
65
|
+
reject(new Error(`Request failed: ${getErrorMessage(error)}`));
|
|
80
66
|
});
|
|
81
67
|
});
|
|
82
68
|
}
|
package/dist/threadsManager.js
CHANGED
|
@@ -145,22 +145,26 @@ export class ThreadsManager {
|
|
|
145
145
|
else if (message.type === 'exit') {
|
|
146
146
|
threadInfo.lastStopped = now;
|
|
147
147
|
threadInfo.lastDuration = Math.max(0, now - (threadInfo.lastStarted ?? now));
|
|
148
|
+
if (!message.success) {
|
|
149
|
+
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
150
|
+
}
|
|
148
151
|
threadInfo.worker = undefined;
|
|
149
152
|
this.log.debug(`Thread ${threadInfo.name} has exited at ${new Date(now).toISOString()} with thread id ${worker.threadId} after running for ${threadInfo.lastDuration} ms`);
|
|
150
153
|
}
|
|
151
154
|
});
|
|
152
155
|
worker.on('messageerror', () => {
|
|
153
156
|
const now = Date.now();
|
|
157
|
+
threadInfo.lastSeen = now;
|
|
154
158
|
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
155
159
|
this.log.error(`Thread ${threadInfo.name} encountered a message error at ${new Date(now).toISOString()}`);
|
|
156
160
|
});
|
|
157
161
|
worker.once('error', (error) => {
|
|
158
162
|
const now = Date.now();
|
|
159
|
-
threadInfo.
|
|
163
|
+
threadInfo.lastSeen = now;
|
|
160
164
|
threadInfo.lastStopped = now;
|
|
161
165
|
threadInfo.lastDuration = Math.max(0, now - (threadInfo.lastStarted ?? now));
|
|
166
|
+
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
162
167
|
threadInfo.worker = undefined;
|
|
163
|
-
threadInfo.lastSeen = now;
|
|
164
168
|
this.log.error(`Thread ${threadInfo.name} encountered an error at ${new Date(now).toISOString()} after running for ${threadInfo.lastDuration} ms: ${getErrorMessage(error)}`);
|
|
165
169
|
});
|
|
166
170
|
this.log.debug(`Started thread ${threadInfo.name} from path ${path} type ${threadInfo.type} with thread id ${worker.threadId}`);
|
package/dist/workerWrapper.d.ts
CHANGED
|
@@ -12,8 +12,14 @@ export declare class WorkerWrapper {
|
|
|
12
12
|
server: BroadcastServer;
|
|
13
13
|
workerData: WorkerData | null;
|
|
14
14
|
tracker: Tracker | undefined;
|
|
15
|
+
private destroyed;
|
|
16
|
+
private readonly boundUnhandledRejectionHandler;
|
|
17
|
+
private readonly boundUncaughtExceptionHandler;
|
|
15
18
|
constructor(name: ThreadNames, callback: (worker: WorkerWrapper) => Promise<boolean>);
|
|
16
19
|
destroy(success: boolean): void;
|
|
20
|
+
private handleUnhandledRejection;
|
|
21
|
+
private handleUncaughtException;
|
|
22
|
+
private safeParentLog;
|
|
17
23
|
parentPost(message: ParentPortMessage): void;
|
|
18
24
|
parentLog(logName: string | undefined, logLevel: LogLevel, message: string): void;
|
|
19
25
|
logger(level: LogLevel, message: string): void;
|
package/dist/workerWrapper.js
CHANGED
|
@@ -17,6 +17,13 @@ export class WorkerWrapper {
|
|
|
17
17
|
server;
|
|
18
18
|
workerData = workerData;
|
|
19
19
|
tracker;
|
|
20
|
+
destroyed = false;
|
|
21
|
+
boundUnhandledRejectionHandler = (reason) => {
|
|
22
|
+
this.handleUnhandledRejection(reason);
|
|
23
|
+
};
|
|
24
|
+
boundUncaughtExceptionHandler = (error) => {
|
|
25
|
+
this.handleUncaughtException(error);
|
|
26
|
+
};
|
|
20
27
|
constructor(name, callback) {
|
|
21
28
|
this.name = name;
|
|
22
29
|
this.callback = callback;
|
|
@@ -45,6 +52,10 @@ export class WorkerWrapper {
|
|
|
45
52
|
logLevel: this.debug ? "debug" : "info",
|
|
46
53
|
});
|
|
47
54
|
this.server = new BroadcastServer('matterbridge', this.log);
|
|
55
|
+
if (!isMainThread) {
|
|
56
|
+
process.on('unhandledRejection', this.boundUnhandledRejectionHandler);
|
|
57
|
+
process.on('uncaughtException', this.boundUncaughtExceptionHandler);
|
|
58
|
+
}
|
|
48
59
|
if (!isMainThread && parentPort && this.workerData) {
|
|
49
60
|
parentPort.on('message', (message) => {
|
|
50
61
|
if (this.debug)
|
|
@@ -92,20 +103,58 @@ export class WorkerWrapper {
|
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
105
|
destroy(success) {
|
|
106
|
+
if (this.destroyed)
|
|
107
|
+
return;
|
|
108
|
+
this.destroyed = true;
|
|
109
|
+
if (!isMainThread) {
|
|
110
|
+
process.off('unhandledRejection', this.boundUnhandledRejectionHandler);
|
|
111
|
+
process.off('uncaughtException', this.boundUncaughtExceptionHandler);
|
|
112
|
+
}
|
|
95
113
|
if (this.tracker)
|
|
96
114
|
this.tracker.stop();
|
|
97
115
|
this.server.close();
|
|
98
116
|
if (!isMainThread && parentPort && this.workerData) {
|
|
99
117
|
if (this.debug)
|
|
100
118
|
this.parentLog(this.name, "info", `Worker ${this.name}:${threadId} exiting with success: ${success}.`);
|
|
101
|
-
|
|
102
|
-
|
|
119
|
+
try {
|
|
120
|
+
this.parentPost({ type: 'exit', threadId, threadName: this.name, memoryUsage: process.memoryUsage(), success });
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
this.log.error(`Worker ${this.name}:${threadId} failed to send exit message to parent: ${getErrorMessage(error)}`);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
parentPort.close();
|
|
127
|
+
process.exit(success ? 0 : 1);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
this.log.error(`Worker ${this.name}:${threadId} failed to close parentPort: ${getErrorMessage(error)}`);
|
|
131
|
+
}
|
|
103
132
|
}
|
|
104
133
|
else {
|
|
105
134
|
if (this.debug)
|
|
106
135
|
this.log.debug(`Worker ${this.name}:${threadId} exiting with success in main thread: ${success}.`);
|
|
107
136
|
}
|
|
108
137
|
}
|
|
138
|
+
handleUnhandledRejection(reason) {
|
|
139
|
+
const errorMessage = inspectError(this.log, `Worker ${this.name} unhandled rejection`, reason);
|
|
140
|
+
this.safeParentLog("error", errorMessage);
|
|
141
|
+
this.destroy(false);
|
|
142
|
+
}
|
|
143
|
+
handleUncaughtException(error) {
|
|
144
|
+
const errorMessage = inspectError(this.log, `Worker ${this.name} uncaught exception`, error);
|
|
145
|
+
this.safeParentLog("error", errorMessage);
|
|
146
|
+
this.destroy(false);
|
|
147
|
+
}
|
|
148
|
+
safeParentLog(level, message) {
|
|
149
|
+
if (this.destroyed)
|
|
150
|
+
return;
|
|
151
|
+
try {
|
|
152
|
+
this.logger(level, message);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
this.log.error(`Worker ${this.name} failed to send error log to parent: ${getErrorMessage(error)}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
109
158
|
parentPost(message) {
|
|
110
159
|
if (!parentPort)
|
|
111
160
|
throw new Error(`WorkerServer ${this.name}: parentPort is not available.`);
|
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-20260629-7c47082",
|
|
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-20260629-7c47082",
|
|
73
|
+
"@matterbridge/utils": "3.9.3-dev-20260629-7c47082",
|
|
74
74
|
"@zip.js/zip.js": "2.8.26",
|
|
75
75
|
"node-ansi-logger": "3.3.0"
|
|
76
76
|
}
|