@platformatic/runtime 2.6.1 → 2.8.0-alpha.1
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 +3 -1
- package/eslint.config.js +1 -1
- package/lib/config.js +1 -1
- package/lib/dependencies.js +15 -13
- package/lib/errors.js +3 -1
- package/lib/logger.js +22 -7
- package/lib/management-api.js +1 -1
- package/lib/runtime.js +317 -204
- package/lib/schema.js +12 -0
- package/lib/start.js +15 -9
- package/lib/worker/app.js +16 -2
- package/lib/worker/itc.js +7 -2
- package/lib/worker/main.js +75 -7
- package/lib/worker/round-robin-map.js +61 -0
- package/lib/worker/symbols.js +6 -1
- package/package.json +16 -15
- package/schema.json +17 -1
package/config.d.ts
CHANGED
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
* and run json-schema-to-typescript to regenerate this file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type HttpsSchemasPlatformaticDevPlatformaticRuntime280Alpha1Json = {
|
|
9
9
|
[k: string]: unknown;
|
|
10
10
|
} & {
|
|
11
11
|
$schema?: string;
|
|
12
12
|
preload?: string;
|
|
13
13
|
entrypoint?: string;
|
|
14
|
+
basePath?: string;
|
|
14
15
|
autoload?: {
|
|
15
16
|
path: string;
|
|
16
17
|
exclude?: string[];
|
|
@@ -25,6 +26,7 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime261Json = {
|
|
|
25
26
|
services?: {
|
|
26
27
|
[k: string]: unknown;
|
|
27
28
|
}[];
|
|
29
|
+
workers?: number;
|
|
28
30
|
web?: {
|
|
29
31
|
[k: string]: unknown;
|
|
30
32
|
}[];
|
package/eslint.config.js
CHANGED
package/lib/config.js
CHANGED
|
@@ -71,7 +71,7 @@ async function _transformConfig (configManager, args) {
|
|
|
71
71
|
const existingServiceId = services.findIndex(service => service.id === id)
|
|
72
72
|
|
|
73
73
|
if (existingServiceId !== -1) {
|
|
74
|
-
services[existingServiceId] = service
|
|
74
|
+
services[existingServiceId] = { ...service, ...services[existingServiceId] }
|
|
75
75
|
} else {
|
|
76
76
|
services.push(service)
|
|
77
77
|
}
|
package/lib/dependencies.js
CHANGED
|
@@ -4,6 +4,7 @@ const Topo = require('@hapi/topo')
|
|
|
4
4
|
const { closest } = require('fastest-levenshtein')
|
|
5
5
|
|
|
6
6
|
const errors = require('./errors')
|
|
7
|
+
const { RoundRobinMap } = require('./worker/round-robin-map')
|
|
7
8
|
|
|
8
9
|
function missingDependencyErrorMessage (clientName, service, services) {
|
|
9
10
|
const closestName = closest(clientName, [...services.keys()])
|
|
@@ -20,15 +21,13 @@ function checkDependencies (services) {
|
|
|
20
21
|
for (const service of services) {
|
|
21
22
|
for (const dependency of service.dependencies) {
|
|
22
23
|
if (dependency.local && !allServices.has(dependency.id)) {
|
|
23
|
-
throw new errors.MissingDependencyError(
|
|
24
|
-
missingDependencyErrorMessage(dependency.id, service, services)
|
|
25
|
-
)
|
|
24
|
+
throw new errors.MissingDependencyError(missingDependencyErrorMessage(dependency.id, service, services))
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
function topologicalSort (
|
|
30
|
+
function topologicalSort (workers, config) {
|
|
32
31
|
const topo = new Topo.Sorter()
|
|
33
32
|
|
|
34
33
|
for (const service of config.services) {
|
|
@@ -39,21 +38,24 @@ function topologicalSort (services, config) {
|
|
|
39
38
|
topo.add(service, {
|
|
40
39
|
group: service.id,
|
|
41
40
|
after: localDependencyIds,
|
|
42
|
-
manual: true
|
|
41
|
+
manual: true
|
|
43
42
|
})
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
config.services = topo.sort()
|
|
47
46
|
|
|
48
|
-
return new
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
return new RoundRobinMap(
|
|
48
|
+
Array.from(workers.entries()).sort((a, b) => {
|
|
49
|
+
if (a[0] === b[0]) {
|
|
50
|
+
return 0
|
|
51
|
+
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
const aIndex = config.services.findIndex(s => s.id === a[0])
|
|
54
|
+
const bIndex = config.services.findIndex(s => s.id === b[0])
|
|
55
|
+
return aIndex - bIndex
|
|
56
|
+
}),
|
|
57
|
+
workers.configuration
|
|
58
|
+
)
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
module.exports = { checkDependencies, topologicalSort }
|
package/lib/errors.js
CHANGED
|
@@ -7,7 +7,9 @@ const ERROR_PREFIX = 'PLT_RUNTIME'
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
AddressInUseError: createError(`${ERROR_PREFIX}_EADDR_IN_USE`, 'The current port is in use by another application'),
|
|
9
9
|
RuntimeExitedError: createError(`${ERROR_PREFIX}_RUNTIME_EXIT`, 'The runtime exited before the operation completed'),
|
|
10
|
-
|
|
10
|
+
// The following two use the same code as we only need to differentiate the label
|
|
11
|
+
ServiceExitedError: createError(`${ERROR_PREFIX}_SERVICE_EXIT`, 'The service "%s" exited prematurely with error code %d'),
|
|
12
|
+
WorkerExitedError: createError(`${ERROR_PREFIX}_SERVICE_EXIT`, 'The worker %s of the service "%s" exited prematurely with error code %d'),
|
|
11
13
|
UnknownRuntimeAPICommandError: createError(`${ERROR_PREFIX}_UNKNOWN_RUNTIME_API_COMMAND`, 'Unknown Runtime API command "%s"'),
|
|
12
14
|
ServiceNotFoundError: createError(`${ERROR_PREFIX}_SERVICE_NOT_FOUND`, 'Service %s not found. Available services are: %s'),
|
|
13
15
|
ServiceNotStartedError: createError(`${ERROR_PREFIX}_SERVICE_NOT_STARTED`, "Service with id '%s' is not started"),
|
package/lib/logger.js
CHANGED
|
@@ -6,17 +6,32 @@ const { isatty } = require('node:tty')
|
|
|
6
6
|
const pino = require('pino')
|
|
7
7
|
const pretty = require('pino-pretty')
|
|
8
8
|
|
|
9
|
+
const customPrettifiers = {
|
|
10
|
+
name (name, _, obj) {
|
|
11
|
+
if (typeof obj.worker !== 'undefined') {
|
|
12
|
+
name += ':' + obj.worker
|
|
13
|
+
obj.worker = undefined // Do not show the worker in a separate line
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return name
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
9
20
|
function createLogger (config, runtimeLogsDir) {
|
|
10
21
|
const loggerConfig = { ...config.logger }
|
|
11
|
-
|
|
22
|
+
|
|
23
|
+
// PLT_RUNTIME_LOGGER_STDOUT is used in test to reduce verbosity
|
|
24
|
+
const cliStream = process.env.PLT_RUNTIME_LOGGER_STDOUT
|
|
25
|
+
? pino.destination(process.env.PLT_RUNTIME_LOGGER_STDOUT)
|
|
26
|
+
: isatty(1)
|
|
27
|
+
? pretty({ customPrettifiers })
|
|
28
|
+
: pino.destination(1)
|
|
12
29
|
|
|
13
30
|
if (!config.managementApi) {
|
|
14
31
|
return [pino(loggerConfig, cliStream), cliStream]
|
|
15
32
|
}
|
|
16
33
|
|
|
17
|
-
const multiStream = pino.multistream([
|
|
18
|
-
{ stream: cliStream, level: loggerConfig.level || 'info' },
|
|
19
|
-
])
|
|
34
|
+
const multiStream = pino.multistream([{ stream: cliStream, level: loggerConfig.level || 'info' }])
|
|
20
35
|
|
|
21
36
|
if (loggerConfig.transport) {
|
|
22
37
|
const transport = pino.transport(loggerConfig.transport)
|
|
@@ -41,9 +56,9 @@ function createLogger (config, runtimeLogsDir) {
|
|
|
41
56
|
mkdir: true,
|
|
42
57
|
fsync: true,
|
|
43
58
|
limit: {
|
|
44
|
-
count: logsLimitCount
|
|
45
|
-
}
|
|
46
|
-
}
|
|
59
|
+
count: logsLimitCount
|
|
60
|
+
}
|
|
61
|
+
}
|
|
47
62
|
})
|
|
48
63
|
|
|
49
64
|
multiStream.add({ level: 'trace', stream: pinoRoll })
|
package/lib/management-api.js
CHANGED
|
@@ -92,7 +92,7 @@ async function managementApiPlugin (app, opts) {
|
|
|
92
92
|
app.post('/services/:id/stop', async request => {
|
|
93
93
|
const { id } = request.params
|
|
94
94
|
app.log.debug('stop service', { id })
|
|
95
|
-
await runtime.
|
|
95
|
+
await runtime.stopService(id)
|
|
96
96
|
})
|
|
97
97
|
|
|
98
98
|
app.all('/services/:id/proxy/*', async (request, reply) => {
|