@platformatic/runtime 3.4.1 → 3.5.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/README.md +1 -1
- package/config.d.ts +224 -77
- package/eslint.config.js +3 -5
- package/index.d.ts +73 -24
- package/index.js +173 -29
- package/lib/config.js +279 -197
- package/lib/errors.js +126 -34
- package/lib/generator.js +640 -0
- package/lib/logger.js +43 -41
- package/lib/management-api.js +109 -118
- package/lib/prom-server.js +202 -16
- package/lib/runtime.js +1963 -585
- package/lib/scheduler.js +119 -0
- package/lib/schema.js +22 -234
- package/lib/shared-http-cache.js +43 -0
- package/lib/upgrade.js +6 -8
- package/lib/utils.js +6 -61
- package/lib/version.js +7 -0
- package/lib/versions/v1.36.0.js +2 -4
- package/lib/versions/v1.5.0.js +2 -4
- package/lib/versions/v2.0.0.js +3 -5
- package/lib/versions/v3.0.0.js +16 -0
- package/lib/worker/controller.js +302 -0
- package/lib/worker/http-cache.js +171 -0
- package/lib/worker/interceptors.js +190 -10
- package/lib/worker/itc.js +146 -59
- package/lib/worker/main.js +220 -81
- package/lib/worker/messaging.js +182 -0
- package/lib/worker/round-robin-map.js +62 -0
- package/lib/worker/shared-context.js +22 -0
- package/lib/worker/symbols.js +14 -5
- package/package.json +47 -38
- package/schema.json +1383 -55
- package/help/compile.txt +0 -8
- package/help/help.txt +0 -5
- package/help/start.txt +0 -21
- package/index.test-d.ts +0 -41
- package/lib/build-server.js +0 -69
- package/lib/compile.js +0 -98
- package/lib/dependencies.js +0 -59
- package/lib/generator/README.md +0 -32
- package/lib/generator/errors.js +0 -10
- package/lib/generator/runtime-generator.d.ts +0 -37
- package/lib/generator/runtime-generator.js +0 -498
- package/lib/start.js +0 -190
- package/lib/worker/app.js +0 -278
- package/lib/worker/default-stackable.js +0 -33
- package/lib/worker/metrics.js +0 -122
- package/runtime.mjs +0 -54
package/index.js
CHANGED
|
@@ -1,29 +1,173 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
import { resolve, validationOptions } from '@platformatic/basic'
|
|
2
|
+
import {
|
|
3
|
+
abstractLogger,
|
|
4
|
+
ensureLoggableError,
|
|
5
|
+
extractModuleFromSchemaUrl,
|
|
6
|
+
findRuntimeConfigurationFile,
|
|
7
|
+
kMetadata,
|
|
8
|
+
loadConfigurationModule,
|
|
9
|
+
loadConfiguration as utilsLoadConfiguration
|
|
10
|
+
} from '@platformatic/foundation'
|
|
11
|
+
import closeWithGrace from 'close-with-grace'
|
|
12
|
+
import inspector from 'node:inspector'
|
|
13
|
+
import { transform, wrapInRuntimeConfig } from './lib/config.js'
|
|
14
|
+
import { NodeInspectorFlagsNotSupportedError } from './lib/errors.js'
|
|
15
|
+
import { Runtime } from './lib/runtime.js'
|
|
16
|
+
import { schema } from './lib/schema.js'
|
|
17
|
+
import { upgrade } from './lib/upgrade.js'
|
|
18
|
+
|
|
19
|
+
async function restartRuntime (runtime) {
|
|
20
|
+
runtime.logger.info('Received SIGUSR2, restarting all applications ...')
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
await runtime.restart()
|
|
24
|
+
} catch (err) {
|
|
25
|
+
runtime.logger.error({ err: ensureLoggableError(err) }, 'Failed to restart applications.')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function handleSignal (runtime, config) {
|
|
30
|
+
// The very first time we add a listener for SIGUSR2,
|
|
31
|
+
// ignore it since it comes from close-with-grace and we want to use to restart the runtime
|
|
32
|
+
function filterCloseWithGraceSIGUSR2 (event, listener) {
|
|
33
|
+
if (event === 'SIGUSR2') {
|
|
34
|
+
process.removeListener('SIGUSR2', listener)
|
|
35
|
+
process.removeListener('newListener', filterCloseWithGraceSIGUSR2)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
process.on('newListener', filterCloseWithGraceSIGUSR2)
|
|
40
|
+
|
|
41
|
+
const cwg = closeWithGrace({ delay: config.gracefulShutdown?.runtime ?? 10000 }, async event => {
|
|
42
|
+
if (event.err instanceof Error) {
|
|
43
|
+
console.error(event.err)
|
|
44
|
+
}
|
|
45
|
+
await runtime.close()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
/* c8 ignore next 3 */
|
|
49
|
+
const restartListener = restartRuntime.bind(null, runtime)
|
|
50
|
+
process.on('SIGUSR2', restartListener)
|
|
51
|
+
|
|
52
|
+
runtime.on('closed', () => {
|
|
53
|
+
process.removeListener('SIGUSR2', restartListener)
|
|
54
|
+
cwg.uninstall()
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function loadConfiguration (configOrRoot, sourceOrConfig, context) {
|
|
59
|
+
const { root, source } = await resolve(configOrRoot, sourceOrConfig, 'runtime')
|
|
60
|
+
|
|
61
|
+
// First of all, load the configuration without any validation
|
|
62
|
+
const config = await utilsLoadConfiguration(source)
|
|
63
|
+
const mod = extractModuleFromSchemaUrl(config)
|
|
64
|
+
if (mod?.module !== '@platformatic/runtime') {
|
|
65
|
+
return wrapInRuntimeConfig(config, context)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return utilsLoadConfiguration(source, context?.schema ?? schema, {
|
|
69
|
+
validationOptions,
|
|
70
|
+
transform,
|
|
71
|
+
upgrade,
|
|
72
|
+
replaceEnv: true,
|
|
73
|
+
root,
|
|
74
|
+
...context
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function loadApplicationsCommands () {
|
|
79
|
+
const applications = {}
|
|
80
|
+
const commands = {}
|
|
81
|
+
const help = {}
|
|
82
|
+
|
|
83
|
+
let config
|
|
84
|
+
try {
|
|
85
|
+
const file = await findRuntimeConfigurationFile(abstractLogger, process.cwd(), null, false, false)
|
|
86
|
+
|
|
87
|
+
/* c8 ignore next 3 - Hard to test */
|
|
88
|
+
if (!file) {
|
|
89
|
+
throw new Error('No runtime configuration file found.')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
config = await loadConfiguration(file)
|
|
93
|
+
|
|
94
|
+
/* c8 ignore next 3 - Hard to test */
|
|
95
|
+
if (!config) {
|
|
96
|
+
throw new Error('No runtime configuration file found.')
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
return { applications, commands, help }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const application of config.applications) {
|
|
103
|
+
try {
|
|
104
|
+
const applicationConfig = await utilsLoadConfiguration(application.config)
|
|
105
|
+
const pkg = await loadConfigurationModule(application.path, applicationConfig)
|
|
106
|
+
|
|
107
|
+
if (pkg.createCommands) {
|
|
108
|
+
const definition = await pkg.createCommands(application.id)
|
|
109
|
+
for (const command of Object.keys(definition.commands)) {
|
|
110
|
+
applications[command] = application
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Object.assign(commands, definition.commands)
|
|
114
|
+
Object.assign(help, definition.help)
|
|
115
|
+
}
|
|
116
|
+
/* c8 ignore next 3 - Hard to test */
|
|
117
|
+
} catch {
|
|
118
|
+
// No-op, ignore the application
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return { applications, commands, help }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export async function create (configOrRoot, sourceOrConfig, context) {
|
|
126
|
+
const config = await loadConfiguration(configOrRoot, sourceOrConfig, context)
|
|
127
|
+
|
|
128
|
+
if (inspector.url() && !config[kMetadata].env.VSCODE_INSPECTOR_OPTIONS) {
|
|
129
|
+
throw new NodeInspectorFlagsNotSupportedError()
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let runtime = new Runtime(config, context)
|
|
133
|
+
handleSignal(runtime, config)
|
|
134
|
+
|
|
135
|
+
// Handle port handling
|
|
136
|
+
if (context?.start) {
|
|
137
|
+
let port = config.server?.port
|
|
138
|
+
|
|
139
|
+
while (true) {
|
|
140
|
+
try {
|
|
141
|
+
await runtime.start()
|
|
142
|
+
break
|
|
143
|
+
} catch (err) {
|
|
144
|
+
if ((err.code !== 'EADDRINUSE' && err.code !== 'EACCES') || context?.skipPortInUseHandling) {
|
|
145
|
+
throw err
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
await runtime.close()
|
|
149
|
+
|
|
150
|
+
// Get the actual port from the error message if original port was 0
|
|
151
|
+
if (!port) {
|
|
152
|
+
const mo = err.message.match(/ address already in use (.+)/)
|
|
153
|
+
const url = new URL(`http://${mo[1]}`)
|
|
154
|
+
port = Number(url.port)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
config.server.port = ++port
|
|
158
|
+
runtime = new Runtime(config, context)
|
|
159
|
+
handleSignal(runtime, config)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return runtime
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export { transform, wrapInRuntimeConfig } from './lib/config.js'
|
|
168
|
+
export * as errors from './lib/errors.js'
|
|
169
|
+
export { RuntimeGenerator as Generator, WrappedGenerator } from './lib/generator.js'
|
|
170
|
+
export { Runtime } from './lib/runtime.js'
|
|
171
|
+
export { schema } from './lib/schema.js'
|
|
172
|
+
export * from './lib/version.js'
|
|
173
|
+
export * as symbols from './lib/worker/symbols.js'
|