@platformatic/runtime 3.28.2 → 3.29.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.
package/lib/errors.js CHANGED
@@ -144,3 +144,7 @@ export const CannotRemoveEntrypointError = createError(
144
144
  `${ERROR_PREFIX}_CANNOT_REMOVE_ENTRYPOINT`,
145
145
  'Cannot remove the entrypoint application.'
146
146
  )
147
+ export const WorkerInterceptorNotReadyError = createError(
148
+ `${ERROR_PREFIX}_WORKER_INTERCEPTOR_NOT_READY`,
149
+ 'The "%s" application worker interceptor is not ready'
150
+ )
package/lib/runtime.js CHANGED
@@ -35,7 +35,8 @@ import {
35
35
  MissingEntrypointError,
36
36
  MissingPprofCapture,
37
37
  RuntimeAbortedError,
38
- WorkerNotFoundError
38
+ WorkerNotFoundError,
39
+ WorkerInterceptorNotReadyError
39
40
  } from './errors.js'
40
41
  import { abstractLogger, createLogger } from './logger.js'
41
42
  import { startManagementApi } from './management-api.js'
@@ -61,7 +62,8 @@ import {
61
62
  kWorkerId,
62
63
  kWorkersBroadcast,
63
64
  kWorkerStartTime,
64
- kWorkerStatus
65
+ kWorkerStatus,
66
+ kInterceptorReadyPromise
65
67
  } from './worker/symbols.js'
66
68
 
67
69
  const kWorkerFile = join(import.meta.dirname, 'worker/main.js')
@@ -1640,11 +1642,13 @@ export class Runtime extends EventEmitter {
1640
1642
  if (enabled) {
1641
1643
  // Store locally
1642
1644
  this.#workers.set(workerId, worker)
1643
-
1644
- // Setup the interceptor
1645
- this.#meshInterceptor.route(applicationId, worker)
1646
1645
  }
1647
1646
 
1647
+ // Setup the interceptor
1648
+ // kInterceptorReadyPromise resolves when the worker
1649
+ // is ready to receive requests: after calling the replaceServer method
1650
+ worker[kInterceptorReadyPromise] = this.#meshInterceptor.route(applicationId, worker)
1651
+
1648
1652
  // Wait for initialization
1649
1653
  await waitEventFromITC(worker, 'init')
1650
1654
 
@@ -1884,6 +1888,8 @@ export class Runtime extends EventEmitter {
1884
1888
  this.#url = workerUrl
1885
1889
  }
1886
1890
 
1891
+ await this.#waitForWorkerInterceptor(worker)
1892
+
1887
1893
  worker[kWorkerStatus] = 'started'
1888
1894
  worker[kWorkerStartTime] = Date.now()
1889
1895
 
@@ -2034,7 +2040,7 @@ export class Runtime extends EventEmitter {
2034
2040
  }
2035
2041
 
2036
2042
  async #discardWorker (worker) {
2037
- this.#meshInterceptor.unroute(worker[kApplicationId], worker, true)
2043
+ await this.#meshInterceptor.unroute(worker[kApplicationId], worker, true)
2038
2044
  worker.removeAllListeners('exit')
2039
2045
  await worker.terminate()
2040
2046
 
@@ -2128,7 +2134,6 @@ export class Runtime extends EventEmitter {
2128
2134
  }
2129
2135
 
2130
2136
  this.#workers.set(workerId, newWorker)
2131
- this.#meshInterceptor.route(applicationId, newWorker)
2132
2137
  } catch (e) {
2133
2138
  newWorker?.terminate?.()
2134
2139
  throw e
@@ -2336,7 +2341,7 @@ export class Runtime extends EventEmitter {
2336
2341
 
2337
2342
  let pinoLog
2338
2343
 
2339
- if (typeof message === 'object') {
2344
+ if (message !== null && typeof message === 'object') {
2340
2345
  pinoLog =
2341
2346
  typeof message.level === 'number' &&
2342
2347
  // We want to accept both pino raw time (number) and time as formatted string
@@ -2794,4 +2799,24 @@ export class Runtime extends EventEmitter {
2794
2799
 
2795
2800
  this.#loggerContext.updatePrefixes(ids)
2796
2801
  }
2802
+
2803
+ async #waitForWorkerInterceptor (worker, timeout = 10000) {
2804
+ const workerId = worker[kId]
2805
+ const applicationId = worker[kApplicationId]
2806
+
2807
+ const interceptorReadyTimeout = setTimeout(() => {
2808
+ this.logger.error(
2809
+ { applicationId, workerId },
2810
+ 'The worker interceptor is not ready after 10s'
2811
+ )
2812
+ throw new WorkerInterceptorNotReadyError(applicationId)
2813
+ }, timeout)
2814
+
2815
+ try {
2816
+ await worker[kInterceptorReadyPromise]
2817
+ worker[kInterceptorReadyPromise] = null
2818
+ } finally {
2819
+ clearTimeout(interceptorReadyTimeout)
2820
+ }
2821
+ }
2797
2822
  }
@@ -11,6 +11,7 @@ export const kWorkerStartTime = Symbol.for('plt.runtime.worker.startTime')
11
11
  export const kInterceptors = Symbol.for('plt.runtime.worker.interceptors')
12
12
  export const kLastHealthCheckELU = Symbol.for('plt.runtime.worker.lastHealthCheckELU')
13
13
  export const kLastWorkerScalerELU = Symbol.for('plt.runtime.worker.lastWorkerScalerELU')
14
+ export const kInterceptorReadyPromise = Symbol.for('plt.runtime.worker.interceptorReadyPromise')
14
15
 
15
16
  // This string marker should be safe to use since it belongs to Unicode private area
16
17
  export const kStderrMarker = '\ue002'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/runtime",
3
- "version": "3.28.2",
3
+ "version": "3.29.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -35,14 +35,14 @@
35
35
  "typescript": "^5.5.4",
36
36
  "undici-oidc-interceptor": "^0.5.0",
37
37
  "why-is-node-running": "^2.2.2",
38
- "@platformatic/db": "3.28.2",
39
- "@platformatic/composer": "3.28.2",
40
- "@platformatic/gateway": "3.28.2",
41
- "@platformatic/node": "3.28.2",
42
- "@platformatic/sql-graphql": "3.28.2",
43
- "@platformatic/service": "3.28.2",
44
- "@platformatic/sql-mapper": "3.28.2",
45
- "@platformatic/wattpm-pprof-capture": "3.28.2"
38
+ "@platformatic/composer": "3.29.0",
39
+ "@platformatic/db": "3.29.0",
40
+ "@platformatic/node": "3.29.0",
41
+ "@platformatic/service": "3.29.0",
42
+ "@platformatic/sql-mapper": "3.29.0",
43
+ "@platformatic/sql-graphql": "3.29.0",
44
+ "@platformatic/wattpm-pprof-capture": "3.29.0",
45
+ "@platformatic/gateway": "3.29.0"
46
46
  },
47
47
  "dependencies": {
48
48
  "@fastify/accepts": "^5.0.0",
@@ -69,14 +69,14 @@
69
69
  "sonic-boom": "^4.2.0",
70
70
  "systeminformation": "^5.27.11",
71
71
  "undici": "^7.0.0",
72
- "undici-thread-interceptor": "^0.15.0",
72
+ "undici-thread-interceptor": "^1.0.0",
73
73
  "ws": "^8.16.0",
74
- "@platformatic/basic": "3.28.2",
75
- "@platformatic/generators": "3.28.2",
76
- "@platformatic/foundation": "3.28.2",
77
- "@platformatic/itc": "3.28.2",
78
- "@platformatic/metrics": "3.28.2",
79
- "@platformatic/telemetry": "3.28.2"
74
+ "@platformatic/basic": "3.29.0",
75
+ "@platformatic/foundation": "3.29.0",
76
+ "@platformatic/generators": "3.29.0",
77
+ "@platformatic/itc": "3.29.0",
78
+ "@platformatic/telemetry": "3.29.0",
79
+ "@platformatic/metrics": "3.29.0"
80
80
  },
81
81
  "engines": {
82
82
  "node": ">=22.19.0"
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/runtime/3.28.2.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/runtime/3.29.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Runtime Config",
5
5
  "type": "object",