@platformatic/runtime 1.45.1 → 1.47.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/fixtures/configs/service-with-env-port.json +33 -0
- package/lib/api-client.js +8 -4
- package/lib/api.js +1 -1
- package/lib/app.js +2 -1
- package/lib/errors.js +1 -0
- package/lib/start.js +51 -12
- package/package.json +11 -11
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://platformatic.dev/schemas/v0.20.0/runtime",
|
|
3
|
+
"entrypoint": "serviceApp",
|
|
4
|
+
"allowCycles": true,
|
|
5
|
+
"hotReload": false,
|
|
6
|
+
"managementApi": false,
|
|
7
|
+
"autoload": {
|
|
8
|
+
"path": "../monorepo",
|
|
9
|
+
"exclude": [
|
|
10
|
+
"docs",
|
|
11
|
+
"composerApp"
|
|
12
|
+
],
|
|
13
|
+
"mappings": {
|
|
14
|
+
"serviceAppWithLogger": {
|
|
15
|
+
"id": "with-logger",
|
|
16
|
+
"config": "platformatic.service.json"
|
|
17
|
+
},
|
|
18
|
+
"serviceAppWithMultiplePlugins": {
|
|
19
|
+
"id": "multi-plugin-service",
|
|
20
|
+
"config": "platformatic.service.json"
|
|
21
|
+
},
|
|
22
|
+
"dbApp": {
|
|
23
|
+
"id": "db-app",
|
|
24
|
+
"config": "platformatic.db.json"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"server":{
|
|
29
|
+
"hostname":"127.0.0.1",
|
|
30
|
+
"port":"{PORT}"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
package/lib/api-client.js
CHANGED
|
@@ -265,6 +265,7 @@ class RuntimeApiClient extends EventEmitter {
|
|
|
265
265
|
metrics = await this.getFormattedMetrics()
|
|
266
266
|
} catch (error) {
|
|
267
267
|
if (!(error instanceof errors.RuntimeExitedError)) {
|
|
268
|
+
// TODO(mcollina): use the logger
|
|
268
269
|
console.error('Error collecting metrics', error)
|
|
269
270
|
}
|
|
270
271
|
return
|
|
@@ -449,19 +450,22 @@ class RuntimeApiClient extends EventEmitter {
|
|
|
449
450
|
|
|
450
451
|
async #sendCommand (command, params = {}) {
|
|
451
452
|
const operationId = randomUUID()
|
|
452
|
-
|
|
453
453
|
this.worker.postMessage({ operationId, command, params })
|
|
454
454
|
const [message] = await Promise.race(
|
|
455
455
|
[once(this, operationId), this.#exitPromise]
|
|
456
456
|
)
|
|
457
457
|
|
|
458
458
|
if (this.#exitCode !== undefined) {
|
|
459
|
+
if (this.exitCode === 1) {
|
|
460
|
+
throw new errors.AddressInUseError()
|
|
461
|
+
}
|
|
459
462
|
throw new errors.RuntimeExitedError()
|
|
460
463
|
}
|
|
461
|
-
|
|
462
|
-
const { error, data } = message
|
|
464
|
+
const { error, data, code } = message
|
|
463
465
|
if (error !== null) {
|
|
464
|
-
|
|
466
|
+
const err = new Error(error)
|
|
467
|
+
err.code = code
|
|
468
|
+
throw err
|
|
465
469
|
}
|
|
466
470
|
|
|
467
471
|
return JSON.parse(data)
|
package/lib/api.js
CHANGED
|
@@ -105,7 +105,7 @@ class RuntimeApi {
|
|
|
105
105
|
const res = await this.#runCommandHandler(command, params)
|
|
106
106
|
return { operationId, error: null, data: JSON.stringify(res || null) }
|
|
107
107
|
} catch (err) {
|
|
108
|
-
return { operationId, error: err.message }
|
|
108
|
+
return { operationId, error: err.message, code: err.code }
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
package/lib/app.js
CHANGED
|
@@ -133,7 +133,8 @@ class PlatformaticApp extends EventEmitter {
|
|
|
133
133
|
/* c8 ignore next 5 */
|
|
134
134
|
} catch (err) {
|
|
135
135
|
this.server.log.error({ err })
|
|
136
|
-
|
|
136
|
+
this.#starting = false
|
|
137
|
+
throw err
|
|
137
138
|
}
|
|
138
139
|
} else {
|
|
139
140
|
// Make sure the server has run all the onReady hooks before returning.
|
package/lib/errors.js
CHANGED
|
@@ -5,6 +5,7 @@ const createError = require('@fastify/error')
|
|
|
5
5
|
const ERROR_PREFIX = 'PLT_RUNTIME'
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
|
+
AddressInUseError: createError(`${ERROR_PREFIX}_EADDR_IN_USE`, 'The current port is in use by another application'),
|
|
8
9
|
RuntimeExitedError: createError(`${ERROR_PREFIX}_RUNTIME_EXIT`, 'The runtime exited before the operation completed'),
|
|
9
10
|
UnknownRuntimeAPICommandError: createError(`${ERROR_PREFIX}_UNKNOWN_RUNTIME_API_COMMAND`, 'Unknown Runtime API command "%s"'),
|
|
10
11
|
ServiceNotFoundError: createError(`${ERROR_PREFIX}_SERVICE_NOT_FOUND`, 'Service not found. Available services are: %s'),
|
package/lib/start.js
CHANGED
|
@@ -16,6 +16,8 @@ const { parseInspectorOptions, wrapConfigInRuntimeConfig } = require('./config')
|
|
|
16
16
|
const { RuntimeApiClient, getRuntimeLogsDir } = require('./api-client.js')
|
|
17
17
|
const errors = require('./errors')
|
|
18
18
|
const pkg = require('../package.json')
|
|
19
|
+
const pino = require('pino')
|
|
20
|
+
const pretty = require('pino-pretty')
|
|
19
21
|
|
|
20
22
|
const kLoaderFile = pathToFileURL(join(__dirname, 'loader.mjs')).href
|
|
21
23
|
const kWorkerFile = join(__dirname, 'worker.js')
|
|
@@ -138,21 +140,58 @@ async function start (args) {
|
|
|
138
140
|
return serviceStart(config.app, args)
|
|
139
141
|
}
|
|
140
142
|
|
|
143
|
+
async function setupAndStartRuntime (config) {
|
|
144
|
+
const MAX_PORT = 65535
|
|
145
|
+
let runtimeConfig
|
|
146
|
+
|
|
147
|
+
if (config.configType === 'runtime') {
|
|
148
|
+
config.configManager.args = config.args
|
|
149
|
+
runtimeConfig = config.configManager
|
|
150
|
+
} else {
|
|
151
|
+
const wrappedConfig = await wrapConfigInRuntimeConfig(config)
|
|
152
|
+
wrappedConfig.args = config.args
|
|
153
|
+
runtimeConfig = wrappedConfig
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
let runtime = await buildRuntime(runtimeConfig)
|
|
157
|
+
|
|
158
|
+
let address = null
|
|
159
|
+
let startErr = null
|
|
160
|
+
const originalPort = runtimeConfig.current.server?.port || 0
|
|
161
|
+
while (address === null) {
|
|
162
|
+
try {
|
|
163
|
+
address = await runtime.start()
|
|
164
|
+
} catch (err) {
|
|
165
|
+
startErr = err
|
|
166
|
+
if (err.code === 'EADDRINUSE') {
|
|
167
|
+
await runtime.close()
|
|
168
|
+
if (runtimeConfig.current.server.port > MAX_PORT) throw err
|
|
169
|
+
runtimeConfig.current.server.port++
|
|
170
|
+
runtime = await buildRuntime(runtimeConfig)
|
|
171
|
+
} else {
|
|
172
|
+
throw err
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (startErr?.code === 'PLT_RUNTIME_EADDR_IN_USE') {
|
|
177
|
+
const logger = pino(pretty({
|
|
178
|
+
translateTime: 'SYS:HH:MM:ss',
|
|
179
|
+
ignore: 'hostname,pid'
|
|
180
|
+
}))
|
|
181
|
+
logger.warn(`Port: ${originalPort} is already in use!`)
|
|
182
|
+
logger.warn(`Starting service on port: ${runtimeConfig.current.server.port}`)
|
|
183
|
+
}
|
|
184
|
+
return { address, runtime }
|
|
185
|
+
}
|
|
186
|
+
|
|
141
187
|
async function startCommand (args) {
|
|
142
188
|
try {
|
|
143
189
|
const config = await loadConfig({}, args)
|
|
144
|
-
let runtime
|
|
145
|
-
|
|
146
|
-
if (config.configType === 'runtime') {
|
|
147
|
-
config.configManager.args = config.args
|
|
148
|
-
runtime = await buildRuntime(config.configManager)
|
|
149
|
-
} else {
|
|
150
|
-
const wrappedConfig = await wrapConfigInRuntimeConfig(config)
|
|
151
|
-
wrappedConfig.args = config.args
|
|
152
|
-
runtime = await buildRuntime(wrappedConfig)
|
|
153
|
-
}
|
|
154
190
|
|
|
155
|
-
const
|
|
191
|
+
const startResult = await setupAndStartRuntime(config)
|
|
192
|
+
|
|
193
|
+
const runtime = startResult.runtime
|
|
194
|
+
const res = startResult.address
|
|
156
195
|
|
|
157
196
|
closeWithGrace(async (event) => {
|
|
158
197
|
if (event.err instanceof Error) {
|
|
@@ -206,4 +245,4 @@ async function startCommand (args) {
|
|
|
206
245
|
}
|
|
207
246
|
}
|
|
208
247
|
|
|
209
|
-
module.exports = { buildRuntime, start, startCommand }
|
|
248
|
+
module.exports = { buildRuntime, start, startCommand, setupAndStartRuntime }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@fastify/express": "^3.0.0",
|
|
21
21
|
"@fastify/formbody": "^7.4.0",
|
|
22
22
|
"@matteo.collina/tspl": "^0.1.1",
|
|
23
|
-
"borp": "^0.
|
|
23
|
+
"borp": "^0.15.0",
|
|
24
24
|
"c8": "^9.1.0",
|
|
25
25
|
"execa": "^8.0.1",
|
|
26
26
|
"express": "^4.18.3",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"typescript": "^5.4.2",
|
|
35
35
|
"undici-oidc-interceptor": "^0.5.0",
|
|
36
36
|
"why-is-node-running": "^2.2.2",
|
|
37
|
-
"@platformatic/sql-graphql": "1.
|
|
38
|
-
"@platformatic/sql-mapper": "1.
|
|
37
|
+
"@platformatic/sql-graphql": "1.47.0",
|
|
38
|
+
"@platformatic/sql-mapper": "1.47.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@fastify/error": "^3.4.1",
|
|
@@ -63,13 +63,13 @@
|
|
|
63
63
|
"undici": "^6.9.0",
|
|
64
64
|
"why-is-node-running": "^2.2.2",
|
|
65
65
|
"ws": "^8.16.0",
|
|
66
|
-
"@platformatic/composer": "1.
|
|
67
|
-
"@platformatic/config": "1.
|
|
68
|
-
"@platformatic/
|
|
69
|
-
"@platformatic/db": "1.
|
|
70
|
-
"@platformatic/telemetry": "1.
|
|
71
|
-
"@platformatic/
|
|
72
|
-
"@platformatic/utils": "1.
|
|
66
|
+
"@platformatic/composer": "1.47.0",
|
|
67
|
+
"@platformatic/config": "1.47.0",
|
|
68
|
+
"@platformatic/service": "1.47.0",
|
|
69
|
+
"@platformatic/db": "1.47.0",
|
|
70
|
+
"@platformatic/telemetry": "1.47.0",
|
|
71
|
+
"@platformatic/generators": "1.47.0",
|
|
72
|
+
"@platformatic/utils": "1.47.0"
|
|
73
73
|
},
|
|
74
74
|
"standard": {
|
|
75
75
|
"ignore": [
|