@platformatic/runtime 3.68.0 → 3.69.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/lib/runtime.js +15 -1
- package/lib/worker/controller.js +30 -8
- package/package.json +17 -17
- package/schema.json +1 -1
package/lib/runtime.js
CHANGED
|
@@ -2865,7 +2865,21 @@ export class Runtime extends EventEmitter {
|
|
|
2865
2865
|
// Setup the interceptor
|
|
2866
2866
|
// kInterceptorReadyPromise resolves when the worker
|
|
2867
2867
|
// is ready to receive requests: after calling the replaceServer method
|
|
2868
|
-
|
|
2868
|
+
//
|
|
2869
|
+
// It is stored, not awaited: #startWorker awaits it later, and only if the
|
|
2870
|
+
// worker is actually started. A worker that is discarded or torn down
|
|
2871
|
+
// before that — a replacement abandoned because the runtime stopped
|
|
2872
|
+
// mid-restart, for instance — leaves the promise with nobody to observe
|
|
2873
|
+
// it. Closing the mesh interceptor rejects any routing still in flight
|
|
2874
|
+
// ('The dispatcher has been closed.'), so that is a routine shutdown
|
|
2875
|
+
// outcome, not an exotic one, and it surfaced as an unhandledRejection
|
|
2876
|
+
// that could take the process down before graceful shutdown finished.
|
|
2877
|
+
//
|
|
2878
|
+
// Attaching a no-op handler marks the rejection observed WITHOUT
|
|
2879
|
+
// swallowing it: the await in #startWorker still sees and reports it.
|
|
2880
|
+
const interceptorReady = this.#meshInterceptor.route(applicationId, worker)
|
|
2881
|
+
interceptorReady.catch(() => {})
|
|
2882
|
+
worker[kInterceptorReadyPromise] = interceptorReady
|
|
2869
2883
|
|
|
2870
2884
|
// Wait for initialization
|
|
2871
2885
|
try {
|
package/lib/worker/controller.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
convertApplicationNameToPrefix,
|
|
2
3
|
ensureLoggableError,
|
|
3
4
|
FileWatcher,
|
|
4
5
|
kHandledError,
|
|
@@ -28,12 +29,27 @@ import { ApplicationAlreadyStartedError, exitCodes, RuntimeNotStartedError } fro
|
|
|
28
29
|
import { getApplicationUrl } from '../utils.js'
|
|
29
30
|
import { markAsPlatformaticDispatcher, refreshGlobalDispatcher } from './interceptors.js'
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Resolves {PLT_<APPLICATION>_URL} placeholders that no environment variable defines, so that
|
|
34
|
+
* applications can reference each other without the user having to set a variable per pair.
|
|
35
|
+
*
|
|
36
|
+
* The mapping is built forwards, from the ids of the applications that actually exist in the runtime
|
|
37
|
+
* to the variable name each of them owns. Parsing the variable name instead would be ambiguous, both
|
|
38
|
+
* because the id to prefix conversion is not reversible ("with-logger" and "with_logger" share a
|
|
39
|
+
* prefix) and because plenty of _URL variables do not name an application at all: a connection string
|
|
40
|
+
* fragment like {VALKEY_URL} or a DSN like {PLT_DATABASE_URL} must keep resolving to nothing rather
|
|
41
|
+
* than silently becoming an HTTP URL.
|
|
42
|
+
*/
|
|
43
|
+
function buildApplicationUrlResolver (applications) {
|
|
44
|
+
const urls = new Map()
|
|
45
|
+
|
|
46
|
+
for (const { id } of applications ?? []) {
|
|
47
|
+
if (id) {
|
|
48
|
+
urls.set(`PLT_${convertApplicationNameToPrefix(id)}_URL`, getApplicationUrl(id))
|
|
49
|
+
}
|
|
34
50
|
}
|
|
35
51
|
|
|
36
|
-
return
|
|
52
|
+
return key => urls.get(key) ?? null
|
|
37
53
|
}
|
|
38
54
|
|
|
39
55
|
function handleUnhandled (app, event, listeners, timeout, err, ...args) {
|
|
@@ -78,6 +94,8 @@ export class Controller extends EventEmitter {
|
|
|
78
94
|
this.capability = null
|
|
79
95
|
this.#fileWatcher = null
|
|
80
96
|
|
|
97
|
+
const onMissingEnv = buildApplicationUrlResolver(runtimeConfig.applications)
|
|
98
|
+
|
|
81
99
|
this.#context = {
|
|
82
100
|
controller: this,
|
|
83
101
|
runtimeConfig: this.runtimeConfig,
|
|
@@ -95,7 +113,10 @@ export class Controller extends EventEmitter {
|
|
|
95
113
|
worker: workerData?.worker,
|
|
96
114
|
resourceLimits: workerData?.resourceLimits,
|
|
97
115
|
hasManagementApi: !!runtimeConfig.managementApi,
|
|
98
|
-
fetchApplicationUrl:
|
|
116
|
+
fetchApplicationUrl: onMissingEnv,
|
|
117
|
+
// Capabilities spread the whole context into their loadConfiguration call, which is what makes
|
|
118
|
+
// the configuration they load resolve application references like the throwaway load below.
|
|
119
|
+
onMissingEnv,
|
|
99
120
|
strictEnv: runtimeConfig.strictEnv
|
|
100
121
|
}
|
|
101
122
|
}
|
|
@@ -143,10 +164,11 @@ export class Controller extends EventEmitter {
|
|
|
143
164
|
// Parse the configuration file the first time to obtain the schema. This load is thrown away:
|
|
144
165
|
// the capability loads the configuration again below and that is the configuration the
|
|
145
166
|
// application actually runs on. This one only has to yield $schema and module, so it must not
|
|
146
|
-
// diverge from the second load in any way the user can observe: it
|
|
147
|
-
//
|
|
148
|
-
//
|
|
167
|
+
// diverge from the second load in any way the user can observe: it resolves environment
|
|
168
|
+
// variables identically, and leaves the strictEnv report to the load the application is
|
|
169
|
+
// built from, which would otherwise be duplicated for every application.
|
|
149
170
|
const unvalidatedConfig = await loadConfiguration(appConfig.config, null, {
|
|
171
|
+
onMissingEnv: this.#context.onMissingEnv,
|
|
150
172
|
strictEnv: false
|
|
151
173
|
})
|
|
152
174
|
const pkg = await loadConfigurationModule(appConfig.path, unvalidatedConfig)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.69.0",
|
|
4
4
|
"description": "Platformatic runtime",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -35,18 +35,18 @@
|
|
|
35
35
|
"pino-abstract-transport": "^2.0.0",
|
|
36
36
|
"pino-sentry-transport": "^1.6.0",
|
|
37
37
|
"split2": "^4.2.0",
|
|
38
|
-
"tstyche": "^
|
|
38
|
+
"tstyche": "^7.0.0",
|
|
39
39
|
"typescript": "~6.0.3",
|
|
40
40
|
"undici-oidc-interceptor": "^0.9.0",
|
|
41
41
|
"why-is-node-running": "^2.2.2",
|
|
42
|
-
"@platformatic/composer": "3.
|
|
43
|
-
"@platformatic/db": "3.
|
|
44
|
-
"@platformatic/gateway": "3.
|
|
45
|
-
"@platformatic/node": "3.
|
|
46
|
-
"@platformatic/service": "3.
|
|
47
|
-
"@platformatic/sql-graphql": "3.
|
|
48
|
-
"@platformatic/sql-mapper": "3.
|
|
49
|
-
"@platformatic/wattpm-pprof-capture": "3.
|
|
42
|
+
"@platformatic/composer": "3.69.0",
|
|
43
|
+
"@platformatic/db": "3.69.0",
|
|
44
|
+
"@platformatic/gateway": "3.69.0",
|
|
45
|
+
"@platformatic/node": "3.69.0",
|
|
46
|
+
"@platformatic/service": "3.69.0",
|
|
47
|
+
"@platformatic/sql-graphql": "3.69.0",
|
|
48
|
+
"@platformatic/sql-mapper": "3.69.0",
|
|
49
|
+
"@platformatic/wattpm-pprof-capture": "3.69.0"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@fastify/accepts": "^5.0.0",
|
|
@@ -77,13 +77,13 @@
|
|
|
77
77
|
"undici": "^7.27.2",
|
|
78
78
|
"undici-thread-interceptor": "^1.3.1",
|
|
79
79
|
"ws": "^8.16.0",
|
|
80
|
-
"@platformatic/
|
|
81
|
-
"@platformatic/
|
|
82
|
-
"@platformatic/
|
|
83
|
-
"@platformatic/metrics": "3.
|
|
84
|
-
"@platformatic/
|
|
85
|
-
"@platformatic/
|
|
86
|
-
"@platformatic/
|
|
80
|
+
"@platformatic/basic": "3.69.0",
|
|
81
|
+
"@platformatic/foundation": "3.69.0",
|
|
82
|
+
"@platformatic/globals": "3.69.0",
|
|
83
|
+
"@platformatic/metrics": "3.69.0",
|
|
84
|
+
"@platformatic/generators": "3.69.0",
|
|
85
|
+
"@platformatic/telemetry": "3.69.0",
|
|
86
|
+
"@platformatic/itc": "3.69.0"
|
|
87
87
|
},
|
|
88
88
|
"engines": {
|
|
89
89
|
"node": ">=22.19.0"
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/3.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/3.69.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Runtime Config",
|
|
5
5
|
"type": "object",
|