@rapidrest/core 1.14.0 → 2.0.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.
Files changed (53) hide show
  1. package/dist/lib/AlertUtils.js +71 -56
  2. package/dist/lib/AlertUtils.js.map +1 -1
  3. package/dist/lib/ApiError.js +8 -1
  4. package/dist/lib/ApiError.js.map +1 -1
  5. package/dist/lib/CacheUtils.js +23 -0
  6. package/dist/lib/CacheUtils.js.map +1 -0
  7. package/dist/lib/ClassLoader.js +48 -44
  8. package/dist/lib/ClassLoader.js.map +1 -1
  9. package/dist/lib/FileUtils.js +133 -60
  10. package/dist/lib/FileUtils.js.map +1 -1
  11. package/dist/lib/JWTUtils.js +250 -145
  12. package/dist/lib/JWTUtils.js.map +1 -1
  13. package/dist/lib/Logger.js +39 -7
  14. package/dist/lib/Logger.js.map +1 -1
  15. package/dist/lib/MemoryStore.js +8 -6
  16. package/dist/lib/MemoryStore.js.map +1 -1
  17. package/dist/lib/MessagingUtils.js +71 -35
  18. package/dist/lib/MessagingUtils.js.map +1 -1
  19. package/dist/lib/NotificationsUtils.js +60 -8
  20. package/dist/lib/NotificationsUtils.js.map +1 -1
  21. package/dist/lib/OASUtils.js +67 -18
  22. package/dist/lib/OASUtils.js.map +1 -1
  23. package/dist/lib/ObjectFactory.js +151 -63
  24. package/dist/lib/ObjectFactory.js.map +1 -1
  25. package/dist/lib/ObjectUtils.js +48 -7
  26. package/dist/lib/ObjectUtils.js.map +1 -1
  27. package/dist/lib/StringUtils.js +55 -21
  28. package/dist/lib/StringUtils.js.map +1 -1
  29. package/dist/lib/TelemetryUtils.js +41 -5
  30. package/dist/lib/TelemetryUtils.js.map +1 -1
  31. package/dist/lib/UserUtils.js +5 -6
  32. package/dist/lib/UserUtils.js.map +1 -1
  33. package/dist/lib/ValidationUtils.js +16 -4
  34. package/dist/lib/ValidationUtils.js.map +1 -1
  35. package/dist/lib/index.js +2 -0
  36. package/dist/lib/index.js.map +1 -1
  37. package/dist/lib/threads/ThreadPool.js +198 -58
  38. package/dist/lib/threads/ThreadPool.js.map +1 -1
  39. package/dist/types/AlertUtils.d.ts +4 -0
  40. package/dist/types/CacheUtils.d.ts +14 -0
  41. package/dist/types/ClassLoader.d.ts +10 -0
  42. package/dist/types/FileUtils.d.ts +23 -7
  43. package/dist/types/JWTUtils.d.ts +88 -18
  44. package/dist/types/MessagingUtils.d.ts +7 -1
  45. package/dist/types/NotificationsUtils.d.ts +30 -0
  46. package/dist/types/ObjectFactory.d.ts +25 -1
  47. package/dist/types/ObjectUtils.d.ts +14 -0
  48. package/dist/types/StringUtils.d.ts +8 -0
  49. package/dist/types/TelemetryUtils.d.ts +19 -1
  50. package/dist/types/ValidationUtils.d.ts +1 -1
  51. package/dist/types/index.d.ts +2 -0
  52. package/dist/types/threads/ThreadPool.d.ts +34 -2
  53. package/package.json +1 -1
@@ -21,10 +21,20 @@ export class Event {
21
21
  this.origin = serviceName ? `${serviceName}:${config.get("version")}` : "unknown";
22
22
  this.type = data.type;
23
23
  this.userId = userId;
24
- // Copy all fields in data to this object
25
24
  const tmp = data;
26
- for (let key in tmp) {
27
- if (key !== "environment" && key !== "origin" && key !== "userId") {
25
+ const protectedFields = new Set([
26
+ "environment",
27
+ "origin",
28
+ "uid",
29
+ "userId",
30
+ "__proto__",
31
+ "constructor",
32
+ "prototype",
33
+ ]);
34
+ for (const key of Object.keys(tmp)) {
35
+ // We intentionally exclude only these fields from copying here. All others, including timestamp
36
+ // the caller can override in order to provide more accurate information about the event.
37
+ if (!protectedFields.has(key)) {
28
38
  this[key] = tmp[key];
29
39
  }
30
40
  }
@@ -40,6 +50,14 @@ export class Event {
40
50
  * The `on` function allows code within the same application or service to listen for outgoing events that have been
41
51
  * sent via the `record` function.
42
52
  *
53
+ * The utility uses an application specific JWT access token for sending telemetry events. The purpose of using an
54
+ * application specific JWT token versus user token is to identify a potentially compromised application server. This
55
+ * also allows the server to send telemetry events on behalf of the user that the user may not otherwise have permission
56
+ * to send.
57
+ *
58
+ * Note: This class is considered a runtime singleton and intentionally uses static state. Do not initialize this
59
+ * class more than once in your application.
60
+ *
43
61
  * @author Jean-Philippe Steinmetz <rapidrests@gmail.com>
44
62
  */
45
63
  export class EventUtils {
@@ -48,7 +66,7 @@ export class EventUtils {
48
66
  *
49
67
  * @param config The application configuration to use.
50
68
  * @param logger The logging utility to use.
51
- * @param jwtToken The user's JWT token to send telemetry events on behalf of.
69
+ * @param jwtToken The application's JWT token to send telemetry events on behalf of.
52
70
  */
53
71
  static async init(config, logger, jwtToken) {
54
72
  EventUtils.config = config;
@@ -86,7 +104,7 @@ export class EventUtils {
86
104
  const response = await axios.post(url, event, {
87
105
  headers: {
88
106
  Authorization: "jwt " + EventUtils.token,
89
- }
107
+ },
90
108
  });
91
109
  }
92
110
  else {
@@ -132,6 +150,24 @@ export class EventUtils {
132
150
  EventUtils.listeners.set(type, callbacks);
133
151
  }
134
152
  }
153
+ /**
154
+ * Unregisters a `callback` previously registered via `on()` for the given event `type`. Since `EventUtils` is
155
+ * a long-lived process-wide singleton, any listener registered dynamically (rather than once at startup) must
156
+ * eventually be removed via this method or its closure - and anything it captures - is retained for the life
157
+ * of the process.
158
+ *
159
+ * @param type The type of event the callback was registered for.
160
+ * @param callback The exact function reference passed to `on()`.
161
+ */
162
+ static off(type, callback) {
163
+ const callbacks = EventUtils.listeners.get(type);
164
+ if (callbacks) {
165
+ const idx = callbacks.indexOf(callback);
166
+ if (idx >= 0) {
167
+ callbacks.splice(idx, 1);
168
+ }
169
+ }
170
+ }
135
171
  }
136
172
  EventUtils.initialized = false;
137
173
  EventUtils.listeners = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"TelemetryUtils.js","sourceRoot":"","sources":["../../src/TelemetryUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TelemetryUtils.js","sourceRoot":"","sources":["../../src/TelemetryUtils.ts"],"names":[],"mappings":"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"}
@@ -34,12 +34,10 @@ export class UserUtils {
34
34
  * @param organizationUids The list of universally unique identifiers to search for.
35
35
  */
36
36
  static hasOrganizations(user, organizationUids) {
37
- if (user && user.orgs && Array.isArray(user.orgs) && Array.isArray(organizationUids)) {
37
+ if (user && Array.isArray(organizationUids)) {
38
38
  for (const organizationUid of organizationUids) {
39
- for (const uid of user.orgs) {
40
- if (uid === organizationUid) {
41
- return true;
42
- }
39
+ if (UserUtils.hasOrganization(user, organizationUid)) {
40
+ return true;
43
41
  }
44
42
  }
45
43
  }
@@ -59,6 +57,7 @@ export class UserUtils {
59
57
  const parts = externalId.split(":");
60
58
  if (parts.length === 2 && parts[0] === type) {
61
59
  result = parts[1];
60
+ break;
62
61
  }
63
62
  }
64
63
  }
@@ -77,7 +76,7 @@ export class UserUtils {
77
76
  if (user.roles) {
78
77
  if (Array.isArray(user.roles)) {
79
78
  result = user.roles.includes(role);
80
- if (!result && orgUid !== "") {
79
+ if (!result && orgUid) {
81
80
  result = user.roles.includes(`${orgUid}.${role}`);
82
81
  }
83
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"UserUtils.js","sourceRoot":"","sources":["../../src/UserUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserUtils.js","sourceRoot":"","sources":["../../src/UserUtils.ts"],"names":[],"mappings":"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"}
@@ -43,10 +43,10 @@ export class ValidationUtils {
43
43
  return val;
44
44
  }
45
45
  /**
46
- * Validates that the provided array is not empty.
46
+ * Validates that the provided array is not empty (nor `null`/`undefined`).
47
47
  */
48
48
  static checkEmpty(val) {
49
- if (val && val.length === 0) {
49
+ if (!val || val.length === 0) {
50
50
  throw new Error("Value cannot be empty.");
51
51
  }
52
52
  return val;
@@ -82,7 +82,9 @@ export class ValidationUtils {
82
82
  * Validates that the provided object is not null or empty.
83
83
  */
84
84
  static checkNull(val) {
85
- if (typeof val !== "boolean" && !val) {
85
+ // `0` is a valid, non-null value (matching `ObjectUtils.validate`'s own nullable convention), so numbers
86
+ // are excluded from the falsy check alongside booleans.
87
+ if (typeof val !== "boolean" && typeof val !== "number" && !val) {
86
88
  throw new Error("Value cannot be null.");
87
89
  }
88
90
  return val;
@@ -127,7 +129,17 @@ export class ValidationUtils {
127
129
  * Validates that the provided value is an entity `version` number (e.g. `value > 0`).
128
130
  */
129
131
  static checkVersion(val) {
130
- const num = Number(val);
132
+ // `Number()` coerces several "empty" inputs - `null`, `""`/whitespace-only strings, `[]` - to `0`
133
+ // rather than `NaN`, which would otherwise let missing/malformed input silently through as if it were
134
+ // a legitimate version `0` instead of being rejected below. `undefined` needs no such guard since
135
+ // `Number(undefined)` already evaluates to `NaN`.
136
+ const isEmpty = val === null ||
137
+ (typeof val === "string" && val.trim() === "") ||
138
+ (Array.isArray(val) && val.length === 0);
139
+ const num = isEmpty ? NaN : Number(val);
140
+ if (isNaN(num)) {
141
+ throw new Error("Value is not a valid version number.");
142
+ }
131
143
  return Math.max(num, 0);
132
144
  }
133
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ValidationUtils.js","sourceRoot":"","sources":["../../src/ValidationUtils.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,kDAAkD;AAClD,+EAA+E;AAC/E,OAAO,SAAS,MAAM,WAAW,CAAC;AAOlC;;GAEG;AACH,MAAM,OAAO,eAAe;IACxB;;;;;;;OAOG;IACI,MAAM,CAAC,KAAK,CAAC,GAAQ,EAAE,IAAiB;QAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,SAAS,CAAC,GAAW;QAC/B,8FAA8F;QAC9F,8FAA8F;QAC9F,2FAA2F;QAC3F,oDAAoD;QACpD,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,UAAU,CAAC,GAAW;QAChC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,UAAU,CAAC,GAAe;QACpC,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,OAAO,CAAC,GAAW;QAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,SAAS,CAAC,GAAW;QAC/B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,SAAS,CAAC,GAAW;QAC/B,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,SAAS,CAAC,GAAQ;QAC5B,IAAI,OAAO,GAAG,KAAK,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,UAAU,CAAC,GAAW;QAChC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,WAAW,CAAC,GAAW;QACjC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,QAAQ,CAAC,GAAW;QAC9B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,SAAS,CAAC,GAAW;QAC/B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,YAAY,CAAC,GAAQ;QAC/B,MAAM,GAAG,GAAW,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;CACJ"}
1
+ {"version":3,"file":"ValidationUtils.js","sourceRoot":"","sources":["../../src/ValidationUtils.ts"],"names":[],"mappings":"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"}
package/dist/lib/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./ApiError.js";
2
2
  export * from "./AlertUtils.js";
3
+ export * from "./CacheUtils.js";
3
4
  export * from "./ClassLoader.js";
4
5
  export * from "./decorators/index.js";
5
6
  export * from "./FileUtils.js";
@@ -7,6 +8,7 @@ export * from "./JWTUtils.js";
7
8
  export * from "./Logger.js";
8
9
  export * from "./MemoryStore.js";
9
10
  export * from "./MessagingUtils.js";
11
+ export * from "./NotificationsUtils.js";
10
12
  export * from "./ObjectFactory.js";
11
13
  export * from "./ObjectUtils.js";
12
14
  export * from "./OASUtils.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC"}
@@ -67,6 +67,10 @@ export class ThreadPool {
67
67
  constructor(max = 0, logger) {
68
68
  /** The maximum number of threads allowed. */
69
69
  this.maxThreads = os.cpus().length;
70
+ /** Tracks workers whose "exit" event has already fired, so a dead worker left in `workers` (e.g. exited
71
+ * without `restartOnExit`) is never sent a message via `postMessage()`, which throws synchronously once a
72
+ * worker has exited. */
73
+ this.exitedWorkers = new WeakSet();
70
74
  // The `os.cpus().length` fallback can never actually be selected: `this.maxThreads`'s field initializer
71
75
  // already evaluates to that same (always-truthy on a real OS) value before the constructor body runs, so
72
76
  // it's only falsy when `os.cpus().length` itself is falsy too. Kept as defense in depth.
@@ -78,7 +82,28 @@ export class ThreadPool {
78
82
  this.shutdown = false;
79
83
  this.workers = new Array();
80
84
  }
81
- createWorker(idx, options) {
85
+ /**
86
+ * @param onRestart Invoked with the replacement `Worker` whenever `restartOnExit` recreates the worker for
87
+ * `idx`. Lets `start()` re-attach its readiness-tracking listeners to the replacement - without this, a
88
+ * worker that crashes and is restarted before ever reporting ready would leave `start()`'s returned promise
89
+ * hanging forever, since nothing would be listening for the *replacement's* readiness signal.
90
+ */
91
+ /**
92
+ * Invokes every callback registered for `type` via `on()`, passing `idx` and optional `data`. Centralizes
93
+ * the "look up listeners, no-op if none registered" dispatch idiom shared by every worker event handler in
94
+ * `createWorker()`/`stop()` below, so a future change to how listeners are invoked - or a new message type
95
+ * that needs routing to a given event - only has to be made in one place instead of risking a hand-copied
96
+ * site being missed (as happened with WorkerMessageType.ERROR previously falling through to "message").
97
+ */
98
+ dispatch(type, idx, data) {
99
+ const listeners = this.callbacks.get(type);
100
+ if (listeners) {
101
+ for (const callback of listeners) {
102
+ callback(idx, data);
103
+ }
104
+ }
105
+ }
106
+ createWorker(idx, options, onRestart) {
82
107
  if (!options.entry || !!options.worker) {
83
108
  options.entry = path.join(_dirname, "ThreadWorkerEntry.js");
84
109
  }
@@ -88,31 +113,48 @@ export class ThreadPool {
88
113
  };
89
114
  this.logger?.debug(`Creating thread worker: ${JSON.stringify(options)}`);
90
115
  const worker = new Worker(options.entry, workerOptions);
91
- worker.on("error", (error) => {
92
- const listeners = this.callbacks.get("error");
93
- if (listeners) {
94
- for (const callback of listeners) {
95
- callback(idx, error);
96
- }
116
+ // Dispatches registered "online" callbacks for entry-mode pools, which have no other way to signal
117
+ // readiness at the application level. Guarded to worker-mode's exclusion (`!options.worker`) so a
118
+ // worker-mode pool - which reports readiness via the WorkerMessageType.ONLINE message handled below -
119
+ // doesn't fire "online" callbacks twice for the same worker.
120
+ worker.on("online", () => {
121
+ if (options && !options.worker) {
122
+ this.dispatch("online", idx);
97
123
  }
98
124
  });
125
+ worker.on("error", (error) => {
126
+ this.dispatch("error", idx, error);
127
+ });
99
128
  worker.on("exit", async (code) => {
129
+ // Mark this worker instance as exited regardless of shutdown/restart state so send()/sendAll()/
130
+ // sendTo() never call postMessage() on it - postMessage() throws synchronously once a worker has
131
+ // exited, and a restarted worker gets a brand new Worker instance anyway so marking the old one here
132
+ // is harmless.
133
+ this.exitedWorkers.add(worker);
100
134
  // While stop() is in progress it fires "exit" callbacks itself, using the authoritative exit code
101
135
  // returned by terminate() - which is what triggers this very event. Firing them again here would
102
136
  // invoke every registered "exit" callback twice per worker for a single stop() call.
103
137
  if (!this.shutdown) {
104
- const listeners = this.callbacks.get("exit");
105
- if (listeners) {
106
- for (const callback of listeners) {
107
- callback(idx, code);
108
- }
109
- }
138
+ this.dispatch("exit", idx, code);
110
139
  }
111
140
  // Restart worker thread
112
141
  if (options?.restartOnExit && !this.shutdown) {
113
142
  worker.removeAllListeners();
114
- const newWorker = this.createWorker(idx, options);
115
- this.workers[idx] = newWorker;
143
+ // createWorker() calls `new Worker(...)`, which can throw synchronously (e.g. non-cloneable
144
+ // workerData, thread-limit/OOM errors) - especially likely in a crash-loop scenario, which is
145
+ // exactly when restartOnExit is most active. This listener is itself async, and Node does not
146
+ // attach a rejection handler to an EventEmitter listener's returned promise, so an uncaught throw
147
+ // here would become an unhandled rejection capable of crashing the whole host process. Routing
148
+ // the failure to "error" listeners instead keeps it recoverable, consistent with how every other
149
+ // worker failure in this file is reported.
150
+ try {
151
+ const newWorker = this.createWorker(idx, options, onRestart);
152
+ this.workers[idx] = newWorker;
153
+ onRestart?.(newWorker);
154
+ }
155
+ catch (error) {
156
+ this.dispatch("error", idx, error);
157
+ }
116
158
  }
117
159
  });
118
160
  worker.on("message", (msg) => {
@@ -121,24 +163,17 @@ export class ThreadPool {
121
163
  this.logger?.log(msg.data);
122
164
  break;
123
165
  case WorkerMessageType.ONLINE:
124
- {
125
- const listeners = this.callbacks.get("online");
126
- if (listeners) {
127
- for (const callback of listeners) {
128
- callback(idx);
129
- }
130
- }
131
- }
166
+ this.dispatch("online", idx);
167
+ break;
168
+ case WorkerMessageType.ERROR:
169
+ // A post-startup runtime error reported by the worker (see ThreadWorkerEntry.js's message
170
+ // handler). Must route to "error" listeners like the native worker.on("error", ...) case
171
+ // above, not fall through to "message" - otherwise anything monitoring failures only via
172
+ // pool.on("error", ...) never learns the worker failed.
173
+ this.dispatch("error", idx, msg.data);
132
174
  break;
133
175
  default:
134
- {
135
- const listeners = this.callbacks.get("message");
136
- if (listeners) {
137
- for (const callback of listeners) {
138
- callback(idx, msg);
139
- }
140
- }
141
- }
176
+ this.dispatch("message", idx, msg);
142
177
  break;
143
178
  }
144
179
  });
@@ -152,61 +187,155 @@ export class ThreadPool {
152
187
  */
153
188
  start(options, num = this.max) {
154
189
  this.shutdown = false;
190
+ // Terminate any workers left over from a previous start() call so they aren't leaked (their thread and
191
+ // listeners would otherwise become unreachable once `this.workers[i]` is overwritten below).
192
+ for (const worker of this.workers) {
193
+ worker.removeAllListeners();
194
+ void worker.terminate();
195
+ }
196
+ this.workers.length = 0;
155
197
  return new Promise((resolve, reject) => {
156
198
  let numReady = 0;
157
- if (!options) {
158
- options = {};
199
+ let settled = false;
200
+ // Copied rather than mutated in place - `options` may be the caller's own object (reused across
201
+ // multiple start() calls, or even frozen), and it shouldn't gain an `allowTs` property - or, via
202
+ // createWorker() below, an `entry` property - that the caller never set themselves. Everything past
203
+ // this point operates on `resolvedOptions`, never the original `options` parameter.
204
+ const resolvedOptions = { ...options };
205
+ resolvedOptions.allowTs = "allowTs" in resolvedOptions ? resolvedOptions.allowTs : true;
206
+ const target = Math.min(num, this.maxThreads);
207
+ if (target <= 0) {
208
+ // Nothing to create; resolve immediately instead of hanging forever waiting for readiness signals
209
+ // that will never arrive.
210
+ this.logger?.debug("No worker threads to create.");
211
+ resolve();
212
+ return;
159
213
  }
160
- options.allowTs = "allowTs" in options ? options.allowTs : true;
161
- for (let i = 0; i < num && i < this.maxThreads; i++) {
162
- const worker = this.createWorker(i, options);
163
- worker.on("online", () => {
164
- if (options && !options.worker) {
214
+ // If any worker fails to start, terminate every worker created during this start() call (the
215
+ // failed one and any siblings that succeeded) before rejecting. Without this, a failed start()
216
+ // leaks running worker threads that the caller has no reference to, since the returned promise
217
+ // is the only thing that told them startup failed - they have no reason to call stop(). `shutdown`
218
+ // is set first (mirroring stop()) so createWorker()'s persistent "exit" handler treats this as a
219
+ // controlled teardown rather than a crash to restart via `restartOnExit`. Listeners are
220
+ // deliberately left attached (unlike the leftover-worker cleanup above) rather than calling
221
+ // `removeAllListeners()`: a worker mid-teardown that still fires a genuine "error" event with no
222
+ // listener left on it would make Node throw and crash the whole process.
223
+ const failStartup = (error) => {
224
+ if (settled) {
225
+ return;
226
+ }
227
+ settled = true;
228
+ clearTimeout(timeoutHandle);
229
+ this.shutdown = true;
230
+ for (const worker of this.workers) {
231
+ void worker.terminate();
232
+ }
233
+ this.workers.length = 0;
234
+ reject(error);
235
+ };
236
+ // Guard against a worker that never reports readiness and never errors either.
237
+ const timeoutMs = resolvedOptions.startupTimeoutMs ?? ThreadPool.START_TIMEOUT_MS;
238
+ const timeoutHandle = setTimeout(() => {
239
+ failStartup(new Error(`Timed out waiting for worker threads to start after ${timeoutMs}ms.`));
240
+ }, timeoutMs);
241
+ timeoutHandle.unref?.();
242
+ const succeed = () => {
243
+ settled = true;
244
+ clearTimeout(timeoutHandle);
245
+ resolve();
246
+ };
247
+ // Attaches the readiness-tracking listeners used to resolve/reject this start() call to `w`. Defined
248
+ // once per slot and re-invoked (via createWorker's `onRestart` hook below) on any replacement worker
249
+ // created by `restartOnExit` before this promise settles, so a worker that crashes and restarts
250
+ // during startup - before ever reporting ready - still lets start() resolve once the *replacement*
251
+ // becomes ready, instead of hanging forever with no listener tracking it.
252
+ const attachReadyListeners = (w) => {
253
+ let ready = false;
254
+ w.on("online", () => {
255
+ if (settled) {
256
+ return;
257
+ }
258
+ if (!resolvedOptions.worker) {
259
+ ready = true;
165
260
  numReady++;
166
261
  }
167
262
  // When all workers have finished being created resolve
168
- if (numReady >= num || numReady >= this.maxThreads) {
169
- resolve();
263
+ if (numReady >= target) {
264
+ succeed();
170
265
  }
171
266
  });
172
- worker.on("message", (msg) => {
267
+ // If a worker fails to start before it ever reaches readiness, reject instead of leaving the
268
+ // returned promise hanging forever.
269
+ w.on("error", (error) => {
270
+ if (!ready) {
271
+ failStartup(error);
272
+ }
273
+ });
274
+ w.on("message", (msg) => {
275
+ if (settled) {
276
+ return;
277
+ }
173
278
  switch (msg.type) {
174
279
  case WorkerMessageType.ERROR:
175
- reject(msg.data);
176
- break;
280
+ failStartup(msg.data);
281
+ return;
177
282
  case WorkerMessageType.ONLINE:
283
+ ready = true;
178
284
  numReady++;
179
285
  break;
180
286
  }
181
287
  // When all workers have finished being created resolve
182
- if (numReady >= num || numReady >= this.maxThreads) {
183
- resolve();
288
+ if (numReady >= target) {
289
+ succeed();
184
290
  }
185
291
  });
292
+ };
293
+ for (let i = 0; i < target; i++) {
294
+ const worker = this.createWorker(i, resolvedOptions, (newWorker) => {
295
+ if (!settled) {
296
+ attachReadyListeners(newWorker);
297
+ }
298
+ });
299
+ attachReadyListeners(worker);
186
300
  this.workers[i] = worker;
187
301
  }
188
302
  this.logger?.debug(`Created ${this.workers.length} worker(s)`);
189
303
  });
190
304
  }
191
305
  /**
192
- * Stops all running thread executions.
306
+ * Stops all running thread executions. Each worker is given `ThreadPool.STOP_GRACE_PERIOD_MS` to gracefully
307
+ * finish its own `stop()` and exit on its own before being force-terminated.
193
308
  */
194
309
  async stop() {
195
310
  const listeners = this.callbacks.get("exit");
196
311
  this.shutdown = true;
197
- // Send the stop signal so the workers know to terminate
312
+ // Send the stop signal so the workers know to shut down gracefully
198
313
  this.sendAll({ type: WorkerMessageType.STOP });
199
- // Give the message above a chance to propogate
200
- await sleep(10);
201
- for (let idx = 0; idx < this.workers.length; idx++) {
202
- const worker = this.workers[idx];
203
- const exitCode = await worker.terminate();
314
+ // Terminate all workers concurrently so shutdown latency is bounded by the slowest worker rather than
315
+ // scaling linearly with pool size. Each worker gets a grace period to exit on its own (i.e. for its
316
+ // ThreadWorker.stop() to actually finish) before being force-terminated, so in-flight cleanup work
317
+ // (flushing writes, closing connections, etc.) isn't cut off by an arbitrary fixed delay.
318
+ await Promise.all(this.workers.map(async (worker, idx) => {
319
+ let exitCode;
320
+ if (this.exitedWorkers.has(worker)) {
321
+ // Already exited (e.g. crashed with no restartOnExit, before stop() was ever called) - there's
322
+ // nothing to wait for or terminate.
323
+ exitCode = 0;
324
+ }
325
+ else {
326
+ const exitedOnOwn = new Promise((resolve) => worker.once("exit", resolve));
327
+ const timedOut = sleep(ThreadPool.STOP_GRACE_PERIOD_MS).then(() => undefined);
328
+ exitCode = await Promise.race([exitedOnOwn, timedOut]);
329
+ if (exitCode === undefined) {
330
+ exitCode = await worker.terminate();
331
+ }
332
+ }
204
333
  if (listeners) {
205
334
  for (const callback of listeners) {
206
335
  callback(idx, exitCode);
207
336
  }
208
337
  }
209
- }
338
+ }));
210
339
  // Drop all terminated workers so `size`/`send()` don't keep referencing dead workers across a
211
340
  // subsequent start()/stop() cycle. `workers` is a `readonly` array reference, so it's truncated in place.
212
341
  this.workers.length = 0;
@@ -237,7 +366,9 @@ export class ThreadPool {
237
366
  let idx = startIdx;
238
367
  do {
239
368
  const worker = this.workers[idx];
240
- if (worker) {
369
+ // Skip a worker that has already exited (e.g. crashed with no restartOnExit) rather than trying the
370
+ // next one - postMessage() throws synchronously on an exited worker.
371
+ if (worker && !this.exitedWorkers.has(worker)) {
241
372
  worker.postMessage(msg);
242
373
  this.lastThread = idx;
243
374
  return;
@@ -247,12 +378,16 @@ export class ThreadPool {
247
378
  throw new Error("No available workers in the pool.");
248
379
  }
249
380
  /**
250
- * Sends the provided message to all worker threads in the pool.
381
+ * Sends the provided message to all worker threads in the pool. Workers that have already exited (e.g.
382
+ * crashed with no `restartOnExit`) are silently skipped rather than throwing, so one dead worker doesn't
383
+ * prevent delivery to every worker after it in the array.
251
384
  * @param msg The message to send to all workers.
252
385
  */
253
386
  sendAll(msg) {
254
387
  for (const worker of this.workers) {
255
- worker.postMessage(msg);
388
+ if (!this.exitedWorkers.has(worker)) {
389
+ worker.postMessage(msg);
390
+ }
256
391
  }
257
392
  }
258
393
  /**
@@ -261,11 +396,16 @@ export class ThreadPool {
261
396
  * @param msg The message to send the next available worker thread.
262
397
  */
263
398
  sendTo(id, msg) {
264
- if (this.workers[id]) {
265
- this.workers[id].postMessage(msg);
399
+ const worker = this.workers[id];
400
+ if (worker && !this.exitedWorkers.has(worker)) {
401
+ worker.postMessage(msg);
266
402
  }
267
403
  }
268
404
  }
405
+ /** The maximum amount of time, in milliseconds, `stop()` waits for a worker to exit on its own before force-terminating it. */
406
+ ThreadPool.STOP_GRACE_PERIOD_MS = 5000;
407
+ /** The default maximum amount of time, in milliseconds, `start()` waits for all workers to report readiness before rejecting. Overridable per-call via `WorkerOptions.startupTimeoutMs`. */
408
+ ThreadPool.START_TIMEOUT_MS = 30000;
269
409
  __decorate([
270
410
  Logger,
271
411
  __metadata("design:type", Object)