@platformatic/runtime 3.67.0 → 4.0.0-new-config.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 +5 -43
- package/index.d.ts +10 -12
- package/index.js +191 -6
- package/lib/config.js +125 -60
- package/lib/errors.js +5 -13
- package/lib/generator.js +19 -92
- package/lib/management-api.js +3 -5
- package/lib/management-handlers.js +3 -5
- package/lib/runtime.js +377 -183
- package/lib/schema.js +1 -1
- package/lib/upgrade.js +16 -1
- package/lib/versions/v4.0.0.js +31 -0
- package/lib/worker/controller.js +51 -55
- package/lib/worker/itc.js +5 -6
- package/lib/worker/main.js +4 -19
- package/lib/worker/symbols.js +2 -0
- package/lib/worker-scaler.js +8 -10
- package/package.json +17 -16
- package/schema.json +33 -147
package/lib/errors.js
CHANGED
|
@@ -13,7 +13,11 @@ export const ERROR_PREFIX = 'PLT_RUNTIME'
|
|
|
13
13
|
|
|
14
14
|
export const AddressInUseError = createError(
|
|
15
15
|
`${ERROR_PREFIX}_EADDR_IN_USE`,
|
|
16
|
-
'
|
|
16
|
+
'Port %d is already in use by applications "%s" and "%s"'
|
|
17
|
+
)
|
|
18
|
+
export const WorkerAddressInUseError = createError(
|
|
19
|
+
`${ERROR_PREFIX}_WORKER_EADDR_IN_USE`,
|
|
20
|
+
'Port %d is already in use by another worker of the application "%s". Multiple workers can share a port only when the reusePort feature is available in your OS, otherwise set "server.portAssignment" to "perWorkerIncrement" in the application configuration or use a single worker.'
|
|
17
21
|
)
|
|
18
22
|
export const RuntimeExitedError = createError(
|
|
19
23
|
`${ERROR_PREFIX}_RUNTIME_EXIT`,
|
|
@@ -98,14 +102,6 @@ export const NoConfigFileFoundError = createError(
|
|
|
98
102
|
`${ERROR_PREFIX}_NO_CONFIG_FILE_FOUND`,
|
|
99
103
|
"No config file found for application '%s'"
|
|
100
104
|
)
|
|
101
|
-
export const InvalidEntrypointError = createError(
|
|
102
|
-
`${ERROR_PREFIX}_INVALID_ENTRYPOINT`,
|
|
103
|
-
"Invalid entrypoint: '%s' does not exist"
|
|
104
|
-
)
|
|
105
|
-
export const MissingEntrypointError = createError(
|
|
106
|
-
`${ERROR_PREFIX}_MISSING_ENTRYPOINT`,
|
|
107
|
-
'Missing application entrypoint.'
|
|
108
|
-
)
|
|
109
105
|
export const MissingDependencyError = createError(`${ERROR_PREFIX}_MISSING_DEPENDENCY`, 'Missing dependency: "%s"')
|
|
110
106
|
export const InspectAndInspectBrkError = createError(
|
|
111
107
|
`${ERROR_PREFIX}_INSPECT_AND_INSPECT_BRK`,
|
|
@@ -228,10 +224,6 @@ export const HealthSignalTypeMustBeStringError = createError(
|
|
|
228
224
|
`${ERROR_PREFIX}_HEALTH_SIGNAL_TYPE_MUST_BE_STRING`,
|
|
229
225
|
'Health signal type must be a string, received "%s"'
|
|
230
226
|
)
|
|
231
|
-
export const CannotRemoveEntrypointError = createError(
|
|
232
|
-
`${ERROR_PREFIX}_CANNOT_REMOVE_ENTRYPOINT`,
|
|
233
|
-
'Cannot remove the entrypoint application.'
|
|
234
|
-
)
|
|
235
227
|
export const WorkerInterceptorNotReadyError = createError(
|
|
236
228
|
`${ERROR_PREFIX}_WORKER_INTERCEPTOR_NOT_READY`,
|
|
237
229
|
'The "%s" application worker interceptor is not ready'
|
package/lib/generator.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import createError from '@fastify/error'
|
|
2
1
|
import {
|
|
3
2
|
createEnvFileTool,
|
|
4
3
|
defaultPackageManager,
|
|
@@ -23,44 +22,20 @@ const engines = {
|
|
|
23
22
|
node: '>=22.19.0'
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const NoApplicationNamedError = createError(
|
|
29
|
-
`${ERROR_PREFIX}_NO_APPLICATION_FOUND`,
|
|
30
|
-
"No application named '%s' has been added to this runtime."
|
|
31
|
-
)
|
|
32
|
-
const NoEntryPointError = createError(`${ERROR_PREFIX}_NO_ENTRYPOINT`, 'No entrypoint had been defined.')
|
|
33
|
-
|
|
34
|
-
function getRuntimeWrappableProperties (skipServer) {
|
|
35
|
-
const wrappableProperties = {
|
|
25
|
+
function getRuntimeWrappableProperties () {
|
|
26
|
+
return {
|
|
36
27
|
logger: {
|
|
37
28
|
level: '{PLT_SERVER_LOGGER_LEVEL}'
|
|
38
29
|
},
|
|
39
30
|
managementApi: '{PLT_MANAGEMENT_API}'
|
|
40
31
|
}
|
|
41
|
-
|
|
42
|
-
if (!skipServer) {
|
|
43
|
-
wrappableProperties.server = {
|
|
44
|
-
hostname: '{PLT_SERVER_HOSTNAME}',
|
|
45
|
-
port: '{PORT}'
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return wrappableProperties
|
|
50
32
|
}
|
|
51
33
|
|
|
52
34
|
function getRuntimeBaseEnvVars (config) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
env.PLT_SERVER_HOSTNAME = '127.0.0.1'
|
|
57
|
-
env.PORT = config.port || 3042
|
|
35
|
+
return {
|
|
36
|
+
PLT_SERVER_LOGGER_LEVEL: config.logLevel || 'info',
|
|
37
|
+
PLT_MANAGEMENT_API: true
|
|
58
38
|
}
|
|
59
|
-
|
|
60
|
-
env.PLT_SERVER_LOGGER_LEVEL = config.logLevel || 'info'
|
|
61
|
-
env.PLT_MANAGEMENT_API = true
|
|
62
|
-
|
|
63
|
-
return env
|
|
64
39
|
}
|
|
65
40
|
|
|
66
41
|
export class RuntimeGenerator extends BaseGenerator {
|
|
@@ -73,7 +48,6 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
73
48
|
this.applicationsFolder = opts.applicationsFolder ?? 'applications'
|
|
74
49
|
this.applications = []
|
|
75
50
|
this.existingApplications = []
|
|
76
|
-
this.entryPoint = null
|
|
77
51
|
this.packageManager = opts.packageManager ?? defaultPackageManager
|
|
78
52
|
}
|
|
79
53
|
|
|
@@ -97,15 +71,6 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
97
71
|
application.setRuntime(this)
|
|
98
72
|
}
|
|
99
73
|
|
|
100
|
-
setEntryPoint (entryPoint) {
|
|
101
|
-
const application =
|
|
102
|
-
this.existingApplications.includes(entryPoint) || this.applications.find(svc => svc.name === entryPoint)
|
|
103
|
-
if (!application) {
|
|
104
|
-
throw new NoApplicationNamedError(entryPoint)
|
|
105
|
-
}
|
|
106
|
-
this.entryPoint = application
|
|
107
|
-
}
|
|
108
|
-
|
|
109
74
|
async generatePackageJson () {
|
|
110
75
|
const template = {
|
|
111
76
|
name: `${this.runtimeName}`,
|
|
@@ -165,8 +130,6 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
165
130
|
|
|
166
131
|
const { PLT_ROOT, ...existingEnvironment } = this.existingConfig[kMetadata].env
|
|
167
132
|
this.config.env = existingEnvironment
|
|
168
|
-
this.config.port = this.config.env.PORT
|
|
169
|
-
this.entryPoint = this.existingConfig.applications.find(svc => svc.entrypoint)
|
|
170
133
|
this.existingApplications = this.existingConfig.applications.map(s => s.id)
|
|
171
134
|
|
|
172
135
|
this.updateRuntimeConfig(this.existingConfigRaw)
|
|
@@ -190,37 +153,42 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
190
153
|
}
|
|
191
154
|
|
|
192
155
|
setApplicationsConfigValues () {
|
|
193
|
-
|
|
156
|
+
let newApplicationOrdinal = 0
|
|
157
|
+
this.applications.forEach(({ name, application }) => {
|
|
194
158
|
if (!application.config) {
|
|
195
159
|
// set default config
|
|
196
160
|
application.setConfig()
|
|
197
161
|
}
|
|
162
|
+
const existingOrdinal = this.existingApplications.indexOf(name)
|
|
163
|
+
const ordinal = existingOrdinal === -1 ? this.existingApplications.length + newApplicationOrdinal++ : existingOrdinal
|
|
164
|
+
this.setApplicationPort(application, ordinal)
|
|
198
165
|
})
|
|
199
166
|
}
|
|
200
167
|
|
|
168
|
+
setApplicationPort (application, ordinal) {
|
|
169
|
+
if (application.config.port === 3042) {
|
|
170
|
+
application.setConfig({ port: 3042 + ordinal })
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
201
174
|
async _getConfigFileContents () {
|
|
202
175
|
const config = {
|
|
203
176
|
$schema: `https://schemas.platformatic.dev/wattpm/${this.platformaticVersion}.json`,
|
|
204
|
-
entrypoint: this.entryPoint.name,
|
|
205
177
|
watch: true,
|
|
206
178
|
autoload: {
|
|
207
179
|
path: this.config.autoload || this.applicationsFolder,
|
|
208
180
|
exclude: ['docs']
|
|
209
181
|
},
|
|
210
|
-
...getRuntimeWrappableProperties(
|
|
182
|
+
...getRuntimeWrappableProperties()
|
|
211
183
|
}
|
|
212
184
|
|
|
213
185
|
return config
|
|
214
186
|
}
|
|
215
187
|
|
|
216
188
|
async _afterPrepare () {
|
|
217
|
-
if (!this.entryPoint) {
|
|
218
|
-
throw new NoEntryPointError()
|
|
219
|
-
}
|
|
220
189
|
const applicationsEnv = await this.prepareApplicationFiles()
|
|
221
190
|
this.addEnvVars({
|
|
222
191
|
...this.config.env,
|
|
223
|
-
...this.getRuntimeEnv(),
|
|
224
192
|
...applicationsEnv
|
|
225
193
|
})
|
|
226
194
|
|
|
@@ -258,21 +226,6 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
258
226
|
|
|
259
227
|
async prepareQuestions () {
|
|
260
228
|
await this.populateFromExistingConfig()
|
|
261
|
-
|
|
262
|
-
if (this.existingConfig) {
|
|
263
|
-
return
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (!this.config.skipServer) {
|
|
267
|
-
// port
|
|
268
|
-
this.questions.push({
|
|
269
|
-
type: 'input',
|
|
270
|
-
name: 'port',
|
|
271
|
-
default: '3042',
|
|
272
|
-
message: 'What port do you want to use?',
|
|
273
|
-
filter: Number
|
|
274
|
-
})
|
|
275
|
-
}
|
|
276
229
|
}
|
|
277
230
|
|
|
278
231
|
setApplicationsDirectory () {
|
|
@@ -322,12 +275,6 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
322
275
|
// do nothing, makes no sense
|
|
323
276
|
}
|
|
324
277
|
|
|
325
|
-
getRuntimeEnv () {
|
|
326
|
-
return {
|
|
327
|
-
PORT: this.config.port
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
278
|
async postInstallActions () {
|
|
332
279
|
for (const { application } of this.applications) {
|
|
333
280
|
await application.postInstallActions()
|
|
@@ -451,6 +398,7 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
451
398
|
})
|
|
452
399
|
}
|
|
453
400
|
applicationInstance.setConfig(baseConfig)
|
|
401
|
+
this.setApplicationPort(applicationInstance, allNewApplicationsNames.indexOf(newApplication.name))
|
|
454
402
|
applicationInstance.setConfigFields(newApplication.fields)
|
|
455
403
|
|
|
456
404
|
const applicationEnvPrefix = `PLT_${applicationInstance.config.envPrefix}`
|
|
@@ -494,18 +442,6 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
494
442
|
contents: JSON.stringify(currrentPackageJson, null, 2)
|
|
495
443
|
})
|
|
496
444
|
|
|
497
|
-
// set new entrypoint if specified
|
|
498
|
-
const newEntrypoint = newConfig.entrypoint
|
|
499
|
-
if (newEntrypoint) {
|
|
500
|
-
// load platformatic.json runtime config
|
|
501
|
-
const runtimePkgConfigFileData = JSON.parse(
|
|
502
|
-
await readFile(join(this.targetDirectory, this.runtimeConfig), 'utf-8')
|
|
503
|
-
)
|
|
504
|
-
|
|
505
|
-
this.setEntryPoint(newEntrypoint)
|
|
506
|
-
runtimePkgConfigFileData.entrypoint = newEntrypoint
|
|
507
|
-
this.updateRuntimeConfig(runtimePkgConfigFileData)
|
|
508
|
-
}
|
|
509
445
|
await this.writeFiles()
|
|
510
446
|
// save new env
|
|
511
447
|
await envTool.save()
|
|
@@ -548,15 +484,6 @@ export class RuntimeGenerator extends BaseGenerator {
|
|
|
548
484
|
tags: ['runtime-env']
|
|
549
485
|
})
|
|
550
486
|
}
|
|
551
|
-
|
|
552
|
-
updateConfigEntryPoint (entrypoint) {
|
|
553
|
-
// This can return null if the generator was not supposed to modify the config
|
|
554
|
-
const configObject = this.getRuntimeConfigFileObject()
|
|
555
|
-
const config = JSON.parse(configObject.contents)
|
|
556
|
-
config.entrypoint = entrypoint
|
|
557
|
-
|
|
558
|
-
this.updateRuntimeConfig(config)
|
|
559
|
-
}
|
|
560
487
|
}
|
|
561
488
|
|
|
562
489
|
export class WrappedGenerator extends BaseGenerator {
|
|
@@ -626,7 +553,7 @@ export class WrappedGenerator extends BaseGenerator {
|
|
|
626
553
|
async #createConfigFile () {
|
|
627
554
|
const config = {
|
|
628
555
|
$schema: `https://schemas.platformatic.dev/${this.module}/${this.platformaticVersion}.json`,
|
|
629
|
-
runtime: getRuntimeWrappableProperties(
|
|
556
|
+
runtime: getRuntimeWrappableProperties()
|
|
630
557
|
}
|
|
631
558
|
|
|
632
559
|
this.addFile({
|
package/lib/management-api.js
CHANGED
|
@@ -14,7 +14,7 @@ import { platform, tmpdir } from 'node:os'
|
|
|
14
14
|
import { dirname, join } from 'node:path'
|
|
15
15
|
import { setTimeout as sleep } from 'node:timers/promises'
|
|
16
16
|
import { createWebSocketStream } from 'ws'
|
|
17
|
-
import {
|
|
17
|
+
import { prepareAddedApplications } from './config.js'
|
|
18
18
|
|
|
19
19
|
const PLATFORMATIC_TMP_DIR = join(tmpdir(), 'platformatic', 'runtimes')
|
|
20
20
|
|
|
@@ -169,11 +169,9 @@ export async function managementApiPlugin (app, opts) {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
|
|
173
|
-
applications[i] = await prepareApplication(config, applications[i], config.workers)
|
|
174
|
-
}
|
|
172
|
+
const prepared = await prepareAddedApplications(config, applications, runtime.getApplicationsIds())
|
|
175
173
|
|
|
176
|
-
const created = await runtime.addApplications(
|
|
174
|
+
const created = await runtime.addApplications(prepared, request.query.start !== 'false')
|
|
177
175
|
reply.code(201)
|
|
178
176
|
return created
|
|
179
177
|
})
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
kMetadata,
|
|
4
4
|
validate
|
|
5
5
|
} from '@platformatic/foundation'
|
|
6
|
-
import {
|
|
6
|
+
import { prepareAddedApplications } from './config.js'
|
|
7
7
|
|
|
8
8
|
const allOperations = [
|
|
9
9
|
'getRuntimeStatus',
|
|
@@ -138,11 +138,9 @@ export function createManagementHandlers (runtime, allowedOperations) {
|
|
|
138
138
|
|
|
139
139
|
validate(applicationSchema, applications, {}, true, config[kMetadata].root)
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
applications[i] = await prepareApplication(config, applications[i], config.workers)
|
|
143
|
-
}
|
|
141
|
+
const prepared = await prepareAddedApplications(config, applications, runtime.getApplicationsIds())
|
|
144
142
|
|
|
145
|
-
return runtime.addApplications(
|
|
143
|
+
return runtime.addApplications(prepared, start)
|
|
146
144
|
})
|
|
147
145
|
|
|
148
146
|
register('removeApplications', async ({ ids }) => {
|