@platformatic/runtime 2.10.0 → 2.12.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/config.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export type HttpsSchemasPlatformaticDevPlatformaticRuntime2100Json = {
8
+ export type HttpsSchemasPlatformaticDevPlatformaticRuntime2120Json = {
9
9
  [k: string]: unknown;
10
10
  } & {
11
11
  $schema?: string;
@@ -104,6 +104,7 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime2100Json = {
104
104
  )[];
105
105
  };
106
106
  };
107
+ startTimeout?: number;
107
108
  restartOnError?: boolean | number;
108
109
  gracefulShutdown?: {
109
110
  runtime: number | string;
@@ -163,6 +164,7 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime2100Json = {
163
164
  watchDisabled?: boolean;
164
165
  [k: string]: unknown;
165
166
  };
167
+ serviceTimeout?: number | string;
166
168
  };
167
169
 
168
170
  export interface UndiciInterceptor {
package/lib/errors.js CHANGED
@@ -13,6 +13,7 @@ module.exports = {
13
13
  UnknownRuntimeAPICommandError: createError(`${ERROR_PREFIX}_UNKNOWN_RUNTIME_API_COMMAND`, 'Unknown Runtime API command "%s"'),
14
14
  ServiceNotFoundError: createError(`${ERROR_PREFIX}_SERVICE_NOT_FOUND`, 'Service %s not found. Available services are: %s'),
15
15
  ServiceNotStartedError: createError(`${ERROR_PREFIX}_SERVICE_NOT_STARTED`, "Service with id '%s' is not started"),
16
+ ServiceStartTimeoutError: createError(`${ERROR_PREFIX}_SERVICE_START_TIMEOUT`, "Service with id '%s' failed to start in %dms."),
16
17
  FailedToRetrieveOpenAPISchemaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_OPENAPI_SCHEMA`, 'Failed to retrieve OpenAPI schema for service with id "%s": %s'),
17
18
  FailedToRetrieveGraphQLSchemaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_GRAPHQL_SCHEMA`, 'Failed to retrieve GraphQL schema for service with id "%s": %s'),
18
19
  FailedToRetrieveMetaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_META`, 'Failed to retrieve metadata for service with id "%s": %s'),
package/lib/runtime.js CHANGED
@@ -79,7 +79,10 @@ class Runtime extends EventEmitter {
79
79
  this.#servicesIds = []
80
80
  this.#url = undefined
81
81
  // Note: nothing hits the main thread so there is no reason to set the globalDispatcher here
82
- this.#interceptor = createThreadInterceptor({ domain: '.plt.local', timeout: true })
82
+ this.#interceptor = createThreadInterceptor({
83
+ domain: '.plt.local',
84
+ timeout: this.#configManager.current.serviceTimeout
85
+ })
83
86
  this.#status = undefined
84
87
  this.#restartingWorkers = new Map()
85
88
  }
@@ -973,7 +976,19 @@ class Runtime extends EventEmitter {
973
976
  worker[kWorkerStatus] = 'starting'
974
977
 
975
978
  try {
976
- const workerUrl = await sendViaITC(worker, 'start')
979
+ let workerUrl
980
+ if (config.startTimeout > 0) {
981
+ workerUrl = await executeWithTimeout(sendViaITC(worker, 'start'), config.startTimeout)
982
+
983
+ if (workerUrl === 'timeout') {
984
+ this.logger.info(`The ${label} failed to start in ${config.startTimeout}ms. Forcefully killing the thread.`)
985
+ worker.terminate()
986
+ throw new errors.ServiceStartTimeoutError(id, config.startTimeout)
987
+ }
988
+ } else {
989
+ workerUrl = await sendViaITC(worker, 'start')
990
+ }
991
+
977
992
  if (workerUrl) {
978
993
  this.#url = workerUrl
979
994
  }
@@ -986,9 +1001,12 @@ class Runtime extends EventEmitter {
986
1001
 
987
1002
  const { enabled, gracePeriod } = worker[kConfig].health
988
1003
  if (enabled && config.restartOnError > 0) {
989
- worker[kHealthCheckTimer] = setTimeout(() => {
990
- this.#setupHealthCheck(worker, label)
991
- }, gracePeriod > 0 ? gracePeriod : 1)
1004
+ worker[kHealthCheckTimer] = setTimeout(
1005
+ () => {
1006
+ this.#setupHealthCheck(worker, label)
1007
+ },
1008
+ gracePeriod > 0 ? gracePeriod : 1
1009
+ )
992
1010
  }
993
1011
  } catch (error) {
994
1012
  // TODO: handle port allocation error here
@@ -1002,7 +1020,9 @@ class Runtime extends EventEmitter {
1002
1020
  await worker.terminate()
1003
1021
  }
1004
1022
 
1005
- this.logger.error({ err: ensureLoggableError(error) }, `Failed to start ${label}.`)
1023
+ if (error.code !== 'PLT_RUNTIME_SERVICE_START_TIMEOUT') {
1024
+ this.logger.error({ err: ensureLoggableError(error) }, `Failed to start ${label}.`)
1025
+ }
1006
1026
 
1007
1027
  const restartOnError = config.restartOnError
1008
1028
 
package/lib/schema.js CHANGED
@@ -108,6 +108,11 @@ const platformaticRuntimeSchema = {
108
108
  web: services,
109
109
  logger,
110
110
  server,
111
+ startTimeout: {
112
+ default: 30000,
113
+ type: 'number',
114
+ minimum: 0
115
+ },
111
116
  restartOnError: {
112
117
  default: true,
113
118
  anyOf: [
@@ -269,6 +274,16 @@ const platformaticRuntimeSchema = {
269
274
  type: 'boolean'
270
275
  }
271
276
  }
277
+ },
278
+ serviceTimeout: {
279
+ anyOf: [
280
+ {
281
+ type: 'number',
282
+ minimum: 1
283
+ },
284
+ { type: 'string' }
285
+ ],
286
+ default: 300000 // 5 minutes
272
287
  }
273
288
  },
274
289
  anyOf: [{ required: ['autoload'] }, { required: ['services'] }, { required: ['web'] }],
package/lib/start.js CHANGED
@@ -31,7 +31,7 @@ async function restartRuntime (runtime) {
31
31
  async function buildRuntime (configManager, env) {
32
32
  env = env || process.env
33
33
 
34
- if (inspector.url()) {
34
+ if (inspector.url() && !env.VSCODE_INSPECTOR_OPTIONS) {
35
35
  throw new errors.NodeInspectorFlagsNotSupportedError()
36
36
  }
37
37
 
@@ -98,9 +98,7 @@ async function main () {
98
98
  setGlobalDispatcher(globalDispatcher)
99
99
 
100
100
  // Setup mesh networker
101
- // The timeout is set to 5 minutes to avoid long term memory leaks
102
- // TODO: make this configurable
103
- const threadDispatcher = wire({ port: parentPort, useNetwork: service.useHttp, timeout: 5 * 60 * 1000 })
101
+ const threadDispatcher = wire({ port: parentPort, useNetwork: service.useHttp, timeout: config.serviceTimeout })
104
102
 
105
103
  // If the service is an entrypoint and runtime server config is defined, use it.
106
104
  let serverConfig = null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/runtime",
3
- "version": "2.10.0",
3
+ "version": "2.12.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -35,12 +35,12 @@
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/composer": "2.10.0",
39
- "@platformatic/db": "2.10.0",
40
- "@platformatic/node": "2.10.0",
41
- "@platformatic/service": "2.10.0",
42
- "@platformatic/sql-mapper": "2.10.0",
43
- "@platformatic/sql-graphql": "2.10.0"
38
+ "@platformatic/composer": "2.12.0",
39
+ "@platformatic/db": "2.12.0",
40
+ "@platformatic/service": "2.12.0",
41
+ "@platformatic/node": "2.12.0",
42
+ "@platformatic/sql-mapper": "2.12.0",
43
+ "@platformatic/sql-graphql": "2.12.0"
44
44
  },
45
45
  "dependencies": {
46
46
  "@fastify/error": "^4.0.0",
@@ -62,22 +62,21 @@
62
62
  "help-me": "^5.0.0",
63
63
  "minimist": "^1.2.8",
64
64
  "pino": "^8.19.0",
65
- "pino-pretty": "^12.0.0",
65
+ "pino-pretty": "^13.0.0",
66
66
  "pino-roll": "^2.0.0",
67
67
  "prom-client": "^15.1.2",
68
68
  "semgrator": "^0.3.0",
69
69
  "tail-file-stream": "^0.2.0",
70
- "thread-cpu-usage": "^0.2.0",
71
70
  "undici": "^6.9.0",
72
- "undici-thread-interceptor": "^0.8.0",
71
+ "undici-thread-interceptor": "^0.9.0",
73
72
  "ws": "^8.16.0",
74
- "@platformatic/basic": "2.10.0",
75
- "@platformatic/generators": "2.10.0",
76
- "@platformatic/config": "2.10.0",
77
- "@platformatic/itc": "2.10.0",
78
- "@platformatic/telemetry": "2.10.0",
79
- "@platformatic/utils": "2.10.0",
80
- "@platformatic/ts-compiler": "2.10.0"
73
+ "@platformatic/basic": "2.12.0",
74
+ "@platformatic/config": "2.12.0",
75
+ "@platformatic/generators": "2.12.0",
76
+ "@platformatic/utils": "2.12.0",
77
+ "@platformatic/itc": "2.12.0",
78
+ "@platformatic/ts-compiler": "2.12.0",
79
+ "@platformatic/telemetry": "2.12.0"
81
80
  },
82
81
  "scripts": {
83
82
  "test": "npm run lint && borp --concurrency=1 --timeout=300000 && tsd",
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.10.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.12.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "type": "object",
5
5
  "properties": {
@@ -654,6 +654,11 @@
654
654
  },
655
655
  "additionalProperties": false
656
656
  },
657
+ "startTimeout": {
658
+ "default": 30000,
659
+ "type": "number",
660
+ "minimum": 0
661
+ },
657
662
  "restartOnError": {
658
663
  "default": true,
659
664
  "anyOf": [
@@ -1051,6 +1056,18 @@
1051
1056
  "type": "boolean"
1052
1057
  }
1053
1058
  }
1059
+ },
1060
+ "serviceTimeout": {
1061
+ "anyOf": [
1062
+ {
1063
+ "type": "number",
1064
+ "minimum": 1
1065
+ },
1066
+ {
1067
+ "type": "string"
1068
+ }
1069
+ ],
1070
+ "default": 300000
1054
1071
  }
1055
1072
  },
1056
1073
  "anyOf": [