@platformatic/basic 3.0.0-alpha.8 → 3.0.0-rc.2

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/config.d.ts CHANGED
@@ -98,6 +98,7 @@ export interface PlatformaticBasicConfig {
98
98
  };
99
99
  startTimeout?: number;
100
100
  restartOnError?: boolean | number;
101
+ exitOnUnhandledErrors?: boolean;
101
102
  gracefulShutdown?: {
102
103
  runtime: number | string;
103
104
  application: number | string;
package/lib/capability.js CHANGED
@@ -458,6 +458,11 @@ export class BaseCapability extends EventEmitter {
458
458
  this.basePath = path
459
459
  })
460
460
 
461
+ this.childManager.on('event', event => {
462
+ globalThis[kITC].notify('event', event)
463
+ this.emit('application:worker:event', config)
464
+ })
465
+
461
466
  // This is not really important for the URL but sometimes it also a sign
462
467
  // that the process has been replaced and thus we need to update the client WebSocket
463
468
  this.childManager.on('url', (url, clientWs) => {
@@ -543,6 +548,7 @@ export class BaseCapability extends EventEmitter {
543
548
  isEntrypoint: this.isEntrypoint,
544
549
  runtimeBasePath: this.runtimeConfig?.basePath ?? null,
545
550
  wantsAbsoluteUrls: meta.gateway?.wantsAbsoluteUrls ?? false,
551
+ exitOnUnhandledErrors: this.runtimeConfig.exitOnUnhandledErrors ?? true,
546
552
  /* c8 ignore next 2 - else */
547
553
  port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
548
554
  host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true,
@@ -719,7 +725,7 @@ export class BaseCapability extends EventEmitter {
719
725
  help: 'Number of active resources keeping the event loop alive',
720
726
  registers: [registry]
721
727
  })
722
- globalThis.platformatic.onActiveResourcesEventLoop = (val) => activeResourcesEventLoopMetric.set(val)
728
+ globalThis.platformatic.onActiveResourcesEventLoop = val => activeResourcesEventLoopMetric.set(val)
723
729
  }
724
730
 
725
731
  async #invalidateHttpCache (opts = {}) {
@@ -112,7 +112,11 @@ export class ChildProcess extends ITC {
112
112
 
113
113
  this.listen()
114
114
  this.#setupLogger()
115
- this.#setupHandlers()
115
+
116
+ if (globalThis.platformatic.exitOnUnhandledErrors) {
117
+ this.#setupHandlers()
118
+ }
119
+
116
120
  this.#setupServer()
117
121
  this.#setupInterceptors()
118
122
 
@@ -288,7 +292,7 @@ export class ChildProcess extends ITC {
288
292
  help: 'Number of active resources keeping the event loop alive',
289
293
  registers: [registry]
290
294
  })
291
- globalThis.platformatic.onActiveResourcesEventLoop = (val) => activeResourcesEventLoopMetric.set(val)
295
+ globalThis.platformatic.onActiveResourcesEventLoop = val => activeResourcesEventLoopMetric.set(val)
292
296
  }
293
297
 
294
298
  async #getMetrics ({ format } = {}) {
@@ -404,6 +408,14 @@ export class ChildProcess extends ITC {
404
408
 
405
409
  process.on('uncaughtException', handleUnhandled.bind(this, 'uncaught exception'))
406
410
  process.on('unhandledRejection', handleUnhandled.bind(this, 'unhandled rejection'))
411
+
412
+ process.on('newListener', event => {
413
+ if (event === 'uncaughtException' || event === 'unhandledRejection') {
414
+ this.#logger.warn(
415
+ `A listener has been added for the "process.${event}" event. This listener will be never triggered as Watt default behavior will kill the process before.\n To disable this behavior, set "exitOnUnhandledErrors" to false in the runtime config.`
416
+ )
417
+ }
418
+ })
407
419
  }
408
420
 
409
421
  #notifyConfig (config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/basic",
3
- "version": "3.0.0-alpha.8",
3
+ "version": "3.0.0-rc.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -25,10 +25,10 @@
25
25
  "split2": "^4.2.0",
26
26
  "undici": "^7.0.0",
27
27
  "ws": "^8.18.0",
28
- "@platformatic/itc": "3.0.0-alpha.8",
29
- "@platformatic/foundation": "3.0.0-alpha.8",
30
- "@platformatic/telemetry": "3.0.0-alpha.8",
31
- "@platformatic/metrics": "3.0.0-alpha.8"
28
+ "@platformatic/foundation": "3.0.0-rc.2",
29
+ "@platformatic/metrics": "3.0.0-rc.2",
30
+ "@platformatic/itc": "3.0.0-rc.2",
31
+ "@platformatic/telemetry": "3.0.0-rc.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "cleaner-spec-reporter": "^0.5.0",
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/basic/3.0.0-alpha.8.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/basic/3.0.0-rc.2.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Basic Config",
5
5
  "type": "object",
@@ -563,6 +563,10 @@
563
563
  }
564
564
  ]
565
565
  },
566
+ "exitOnUnhandledErrors": {
567
+ "default": true,
568
+ "type": "boolean"
569
+ },
566
570
  "gracefulShutdown": {
567
571
  "type": "object",
568
572
  "properties": {
@@ -1,59 +0,0 @@
1
- import { ensureLoggableError } from '@platformatic/foundation'
2
- import { generateRequest, sanitize } from '@platformatic/itc/lib/index.js'
3
- import { once } from 'node:events'
4
- import { platform } from 'node:os'
5
- import { workerData } from 'node:worker_threads'
6
- import build from 'pino-abstract-transport'
7
- import { WebSocket } from 'ws'
8
- import { getSocketPath } from './child-manager.js'
9
-
10
- /* c8 ignore next 5 */
11
- function logDirectError (message, error) {
12
- process._rawDebug(`Logger thread for child process of application ${workerData.id} ${message}.`, {
13
- error: ensureLoggableError(error)
14
- })
15
- }
16
-
17
- /* c8 ignore next 4 */
18
- function handleUnhandled (type, error) {
19
- logDirectError(`threw an ${type}`, error)
20
- process.exit(6)
21
- }
22
-
23
- process.on('uncaughtException', handleUnhandled.bind(null, 'uncaught exception'))
24
- process.on('unhandledRejection', handleUnhandled.bind(null, 'unhandled rejection'))
25
-
26
- export default async function () {
27
- try {
28
- /* c8 ignore next */
29
- const protocol = platform() === 'win32' ? 'ws+unix:' : 'ws+unix://'
30
- const socket = new WebSocket(`${protocol}${getSocketPath(process.env.PLT_MANAGER_ID)}`)
31
-
32
- await once(socket, 'open')
33
-
34
- // Do not process responses but empty the socket inbound queue
35
- socket.on('message', () => {})
36
-
37
- /* c8 ignore next 3 */
38
- socket.on('error', error => {
39
- logDirectError('threw a socket error', error)
40
- })
41
-
42
- return build(
43
- async function (source) {
44
- for await (const obj of source) {
45
- socket.send(JSON.stringify(sanitize(generateRequest('log', { logs: [obj] }))))
46
- }
47
- },
48
- {
49
- close (_, cb) {
50
- socket.close()
51
- cb()
52
- }
53
- }
54
- )
55
- /* c8 ignore next 3 */
56
- } catch (error) {
57
- logDirectError('threw a connection error', error)
58
- }
59
- }