@platformatic/runtime 3.35.1 → 3.37.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
@@ -301,6 +301,10 @@ export type PlatformaticRuntimeConfig = {
301
301
  logs?: {
302
302
  maxSize?: number;
303
303
  };
304
+ /**
305
+ * Custom path for the control socket. If not specified, uses the default platform-specific location.
306
+ */
307
+ socket?: string;
304
308
  };
305
309
  metrics?:
306
310
  | boolean
@@ -513,6 +517,7 @@ export type PlatformaticRuntimeConfig = {
513
517
  [k: string]: unknown;
514
518
  };
515
519
  applicationTimeout?: number | string;
520
+ startupConcurrency?: number | string;
516
521
  messagingTimeout?: number | string;
517
522
  resolvedApplicationsBasePath?: string;
518
523
  env?: {
package/lib/config.js CHANGED
@@ -230,37 +230,44 @@ export async function prepareApplication (config, application, defaultWorkers) {
230
230
  application.config = resolvePath(application.path, application.config)
231
231
  }
232
232
 
233
- try {
234
- let pkg
233
+ // Skip capability detection for external services (url without path)
234
+ // These services will have their path resolved later in runtime.js #setupApplication
235
+ // Attempting to detect capability here would cause slow glob operations on the cwd
236
+ if (application.url && !application.path) {
237
+ application.type = 'unknown'
238
+ } else {
239
+ try {
240
+ let pkg
235
241
 
236
- if (application.config) {
237
- const config = await loadConfiguration(application.config)
238
- pkg = await loadConfigurationModule(application.path, config)
242
+ if (application.config) {
243
+ const config = await loadConfiguration(application.config)
244
+ pkg = await loadConfigurationModule(application.path, config)
239
245
 
240
- application.type = extractModuleFromSchemaUrl(config, true).module
241
- application.skipTelemetryHooks = pkg.skipTelemetryHooks
242
- } else {
243
- const { moduleName, capability } = await importCapabilityAndConfig(application.path)
244
- pkg = capability
246
+ application.type = extractModuleFromSchemaUrl(config, true).module
247
+ application.skipTelemetryHooks = pkg.skipTelemetryHooks
248
+ } else {
249
+ const { moduleName, capability } = await importCapabilityAndConfig(application.path)
250
+ pkg = capability
245
251
 
246
- application.type = moduleName
247
- }
252
+ application.type = moduleName
253
+ }
248
254
 
249
- application.skipTelemetryHooks = pkg.skipTelemetryHooks
255
+ application.skipTelemetryHooks = pkg.skipTelemetryHooks
250
256
 
251
- // This is needed to work around Rust bug on dylibs:
252
- // https://github.com/rust-lang/rust/issues/91979
253
- // https://github.com/rollup/rollup/issues/5761
254
- const _require = createRequire(application.path)
255
- for (const m of pkg.modulesToLoad ?? []) {
256
- const toLoad = _require.resolve(m)
257
- loadModule(_require, toLoad).catch(() => {})
257
+ // This is needed to work around Rust bug on dylibs:
258
+ // https://github.com/rust-lang/rust/issues/91979
259
+ // https://github.com/rollup/rollup/issues/5761
260
+ const _require = createRequire(application.path)
261
+ for (const m of pkg.modulesToLoad ?? []) {
262
+ const toLoad = _require.resolve(m)
263
+ loadModule(_require, toLoad).catch(() => {})
264
+ }
265
+ } catch (err) {
266
+ // This should not happen, it happens on running some unit tests if we prepare the runtime
267
+ // when not all the applications configs are available. Given that we are running this only
268
+ // to ddetermine the type of the application, it's safe to ignore this error and default to unknown
269
+ application.type = 'unknown'
258
270
  }
259
- } catch (err) {
260
- // This should not happen, it happens on running some unit tests if we prepare the runtime
261
- // when not all the applications configs are available. Given that we are running this only
262
- // to ddetermine the type of the application, it's safe to ignore this error and default to unknown
263
- application.type = 'unknown'
264
271
  }
265
272
 
266
273
  // Validate and coerce per-service workers
@@ -328,16 +328,19 @@ export async function managementApiPlugin (app, opts) {
328
328
  })
329
329
  }
330
330
 
331
- export async function startManagementApi (runtime) {
331
+ export async function startManagementApi (runtime, config) {
332
332
  const runtimePID = process.pid
333
+ const customSocket = typeof config === 'object' ? config?.socket : null
333
334
 
334
335
  const runtimePIDDir = join(PLATFORMATIC_TMP_DIR, runtimePID.toString())
335
- if (platform() !== 'win32') {
336
+ if (platform() !== 'win32' && !customSocket) {
336
337
  await createDirectory(runtimePIDDir, true)
337
338
  }
338
339
 
339
340
  let socketPath = null
340
- if (platform() === 'win32') {
341
+ if (customSocket) {
342
+ socketPath = customSocket
343
+ } else if (platform() === 'win32') {
341
344
  socketPath = '\\\\.\\pipe\\platformatic-' + runtimePID.toString()
342
345
  } else {
343
346
  socketPath = join(runtimePIDDir, 'socket')
@@ -348,7 +351,7 @@ export async function startManagementApi (runtime) {
348
351
  managementApi.register(managementApiPlugin, { runtime, prefix: '/api/v1' })
349
352
 
350
353
  managementApi.addHook('onClose', async () => {
351
- if (platform() !== 'win32') {
354
+ if (platform() !== 'win32' && !customSocket) {
352
355
  await safeRemove(runtimePIDDir)
353
356
  }
354
357
  })
package/lib/runtime.js CHANGED
@@ -92,7 +92,7 @@ function parseOrigins (origins) {
92
92
  }
93
93
 
94
94
  // Always run operations in parallel to avoid deadlocks when services have dependencies
95
- const MAX_CONCURRENCY = availableParallelism()
95
+ const DEFAULT_CONCURRENCY = availableParallelism() * 2
96
96
  const MAX_BOOTSTRAP_ATTEMPTS = 5
97
97
  const IMMEDIATE_RESTART_MAX_THRESHOLD = 10
98
98
  const MAX_WORKERS = 100
@@ -151,7 +151,7 @@ export class Runtime extends EventEmitter {
151
151
  this.#env = config[kMetadata].env
152
152
  this.#context = context ?? {}
153
153
  this.#isProduction = this.#context.isProduction ?? this.#context.production ?? false
154
- this.#concurrency = this.#context.concurrency ?? MAX_CONCURRENCY
154
+ this.#concurrency = Math.max(1, config.startupConcurrency ?? this.#context.concurrency ?? DEFAULT_CONCURRENCY)
155
155
  this.#applications = new Map()
156
156
  this.#workers = new RoundRobinMap()
157
157
  this.#url = undefined
@@ -210,7 +210,7 @@ export class Runtime extends EventEmitter {
210
210
  const config = this.#config
211
211
 
212
212
  if (config.managementApi) {
213
- this.#managementApi = await startManagementApi(this, this.#root)
213
+ this.#managementApi = await startManagementApi(this, config.managementApi)
214
214
  }
215
215
 
216
216
  if (config.metrics) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/runtime",
3
- "version": "3.35.1",
3
+ "version": "3.37.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/composer": "3.35.1",
39
- "@platformatic/db": "3.35.1",
40
- "@platformatic/node": "3.35.1",
41
- "@platformatic/gateway": "3.35.1",
42
- "@platformatic/service": "3.35.1",
43
- "@platformatic/sql-graphql": "3.35.1",
44
- "@platformatic/sql-mapper": "3.35.1",
45
- "@platformatic/wattpm-pprof-capture": "3.35.1"
38
+ "@platformatic/composer": "3.37.0",
39
+ "@platformatic/db": "3.37.0",
40
+ "@platformatic/gateway": "3.37.0",
41
+ "@platformatic/node": "3.37.0",
42
+ "@platformatic/sql-graphql": "3.37.0",
43
+ "@platformatic/service": "3.37.0",
44
+ "@platformatic/sql-mapper": "3.37.0",
45
+ "@platformatic/wattpm-pprof-capture": "3.37.0"
46
46
  },
47
47
  "dependencies": {
48
48
  "@fastify/accepts": "^5.0.0",
@@ -71,12 +71,12 @@
71
71
  "undici": "^7.0.0",
72
72
  "undici-thread-interceptor": "^1.3.0",
73
73
  "ws": "^8.16.0",
74
- "@platformatic/foundation": "3.35.1",
75
- "@platformatic/basic": "3.35.1",
76
- "@platformatic/generators": "3.35.1",
77
- "@platformatic/itc": "3.35.1",
78
- "@platformatic/metrics": "3.35.1",
79
- "@platformatic/telemetry": "3.35.1"
74
+ "@platformatic/basic": "3.37.0",
75
+ "@platformatic/foundation": "3.37.0",
76
+ "@platformatic/generators": "3.37.0",
77
+ "@platformatic/itc": "3.37.0",
78
+ "@platformatic/telemetry": "3.37.0",
79
+ "@platformatic/metrics": "3.37.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.35.1.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/runtime/3.37.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Runtime Config",
5
5
  "type": "object",
@@ -2070,6 +2070,10 @@
2070
2070
  }
2071
2071
  },
2072
2072
  "additionalProperties": false
2073
+ },
2074
+ "socket": {
2075
+ "type": "string",
2076
+ "description": "Custom path for the control socket. If not specified, uses the default platform-specific location."
2073
2077
  }
2074
2078
  },
2075
2079
  "additionalProperties": false
@@ -2579,6 +2583,17 @@
2579
2583
  ],
2580
2584
  "default": 300000
2581
2585
  },
2586
+ "startupConcurrency": {
2587
+ "anyOf": [
2588
+ {
2589
+ "type": "number",
2590
+ "minimum": 1
2591
+ },
2592
+ {
2593
+ "type": "string"
2594
+ }
2595
+ ]
2596
+ },
2582
2597
  "messagingTimeout": {
2583
2598
  "anyOf": [
2584
2599
  {