@platformatic/runtime 2.8.2-alpha.1 → 2.9.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 +1 -12
- package/lib/management-api.js +0 -9
- package/lib/runtime.js +3 -48
- package/lib/schema.js +0 -26
- package/lib/worker/main.js +5 -40
- package/package.json +15 -16
- package/schema.json +1 -30
- package/lib/shared-http-cache.js +0 -45
- package/lib/worker/http-cache.js +0 -83
package/config.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and run json-schema-to-typescript to regenerate this file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type HttpsSchemasPlatformaticDevPlatformaticRuntime290Json = {
|
|
9
9
|
[k: string]: unknown;
|
|
10
10
|
} & {
|
|
11
11
|
$schema?: string;
|
|
@@ -115,17 +115,6 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime282Alpha1Json = {
|
|
|
115
115
|
};
|
|
116
116
|
[k: string]: unknown;
|
|
117
117
|
};
|
|
118
|
-
httpCache?:
|
|
119
|
-
| boolean
|
|
120
|
-
| {
|
|
121
|
-
store?: string;
|
|
122
|
-
/**
|
|
123
|
-
* @minItems 1
|
|
124
|
-
*/
|
|
125
|
-
methods?: [string, ...string[]];
|
|
126
|
-
cacheTagsHeader?: string;
|
|
127
|
-
[k: string]: unknown;
|
|
128
|
-
};
|
|
129
118
|
watch?: boolean | string;
|
|
130
119
|
managementApi?:
|
|
131
120
|
| boolean
|
package/lib/management-api.js
CHANGED
|
@@ -193,15 +193,6 @@ async function managementApiPlugin (app, opts) {
|
|
|
193
193
|
const logFileStream = await runtime.getLogFileStream(logId, runtimePID)
|
|
194
194
|
return logFileStream
|
|
195
195
|
})
|
|
196
|
-
|
|
197
|
-
app.get('/http-cache/requests', async () => {
|
|
198
|
-
return runtime.getCachedHttpRequests()
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
app.post('/http-cache/invalidate', async (req) => {
|
|
202
|
-
const { origin, routes, tags } = req.body
|
|
203
|
-
await runtime.invalidateHttpCache({ origin, routes, tags })
|
|
204
|
-
})
|
|
205
196
|
}
|
|
206
197
|
|
|
207
198
|
async function startManagementApi (runtime, configManager) {
|
package/lib/runtime.js
CHANGED
|
@@ -16,7 +16,6 @@ const errors = require('./errors')
|
|
|
16
16
|
const { createLogger } = require('./logger')
|
|
17
17
|
const { startManagementApi } = require('./management-api')
|
|
18
18
|
const { startPrometheusServer } = require('./prom-server')
|
|
19
|
-
const { createSharedStore } = require('./shared-http-cache')
|
|
20
19
|
const { getRuntimeTmpDir } = require('./utils')
|
|
21
20
|
const { sendViaITC, waitEventFromITC } = require('./worker/itc')
|
|
22
21
|
const { RoundRobinMap } = require('./worker/round-robin-map.js')
|
|
@@ -66,7 +65,6 @@ class Runtime extends EventEmitter {
|
|
|
66
65
|
#inspectorServer
|
|
67
66
|
#workers
|
|
68
67
|
#restartingWorkers
|
|
69
|
-
#sharedHttpCache
|
|
70
68
|
|
|
71
69
|
constructor (configManager, runtimeLogsDir, env) {
|
|
72
70
|
super()
|
|
@@ -83,7 +81,6 @@ class Runtime extends EventEmitter {
|
|
|
83
81
|
this.#interceptor = createThreadInterceptor({ domain: '.plt.local', timeout: true })
|
|
84
82
|
this.#status = undefined
|
|
85
83
|
this.#restartingWorkers = new Map()
|
|
86
|
-
this.#sharedHttpCache = null
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
async init () {
|
|
@@ -130,16 +127,6 @@ class Runtime extends EventEmitter {
|
|
|
130
127
|
throw e
|
|
131
128
|
}
|
|
132
129
|
|
|
133
|
-
this.#sharedHttpCache = createSharedStore(
|
|
134
|
-
this.#configManager.dirname,
|
|
135
|
-
{
|
|
136
|
-
...config.httpCache,
|
|
137
|
-
errorCallback: (err) => {
|
|
138
|
-
this.logger.error(err, 'Error in shared HTTP cache store')
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
)
|
|
142
|
-
|
|
143
130
|
this.#updateStatus('init')
|
|
144
131
|
}
|
|
145
132
|
|
|
@@ -268,10 +255,6 @@ class Runtime extends EventEmitter {
|
|
|
268
255
|
this.#loggerDestination = null
|
|
269
256
|
}
|
|
270
257
|
|
|
271
|
-
if (this.#sharedHttpCache?.close) {
|
|
272
|
-
await this.#sharedHttpCache.close()
|
|
273
|
-
}
|
|
274
|
-
|
|
275
258
|
this.#updateStatus('closed')
|
|
276
259
|
}
|
|
277
260
|
|
|
@@ -734,24 +717,6 @@ class Runtime extends EventEmitter {
|
|
|
734
717
|
return createReadStream(filePath)
|
|
735
718
|
}
|
|
736
719
|
|
|
737
|
-
async getCachedHttpRequests () {
|
|
738
|
-
return this.#sharedHttpCache.getRoutes()
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
async invalidateHttpCache (options = {}) {
|
|
742
|
-
const { origin, routes, tags } = options
|
|
743
|
-
|
|
744
|
-
if (!this.#sharedHttpCache) return
|
|
745
|
-
|
|
746
|
-
if (routes && routes.length > 0) {
|
|
747
|
-
await this.#sharedHttpCache.deleteRoutes(routes)
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
if (tags && tags.length > 0) {
|
|
751
|
-
await this.#sharedHttpCache.deleteByCacheTags(origin, tags)
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
|
|
755
720
|
#updateStatus (status) {
|
|
756
721
|
this.#status = status
|
|
757
722
|
this.emit(status)
|
|
@@ -890,19 +855,9 @@ class Runtime extends EventEmitter {
|
|
|
890
855
|
port: worker,
|
|
891
856
|
handlers: {
|
|
892
857
|
getServiceMeta: this.getServiceMeta.bind(this),
|
|
893
|
-
listServices: () =>
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
getHttpCacheValue: opts => this.#sharedHttpCache.getValue(opts.request),
|
|
897
|
-
setHttpCacheValue: opts => this.#sharedHttpCache.setValue(
|
|
898
|
-
opts.request,
|
|
899
|
-
opts.response,
|
|
900
|
-
opts.payload
|
|
901
|
-
),
|
|
902
|
-
deleteHttpCacheValue: opts => this.#sharedHttpCache.deleteByOrigin(
|
|
903
|
-
opts.origin
|
|
904
|
-
),
|
|
905
|
-
invalidateHttpCache: opts => this.invalidateHttpCache(opts),
|
|
858
|
+
listServices: () => {
|
|
859
|
+
return this.#servicesIds
|
|
860
|
+
}
|
|
906
861
|
}
|
|
907
862
|
})
|
|
908
863
|
worker[kITC].listen()
|
package/lib/schema.js
CHANGED
|
@@ -185,32 +185,6 @@ const platformaticRuntimeSchema = {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
},
|
|
188
|
-
httpCache: {
|
|
189
|
-
oneOf: [
|
|
190
|
-
{
|
|
191
|
-
type: 'boolean'
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
type: 'object',
|
|
195
|
-
properties: {
|
|
196
|
-
store: {
|
|
197
|
-
type: 'string'
|
|
198
|
-
},
|
|
199
|
-
methods: {
|
|
200
|
-
type: 'array',
|
|
201
|
-
items: {
|
|
202
|
-
type: 'string'
|
|
203
|
-
},
|
|
204
|
-
default: ['GET', 'HEAD'],
|
|
205
|
-
minItems: 1
|
|
206
|
-
},
|
|
207
|
-
cacheTagsHeader: {
|
|
208
|
-
type: 'string'
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
]
|
|
213
|
-
},
|
|
214
188
|
watch: {
|
|
215
189
|
anyOf: [
|
|
216
190
|
{
|
package/lib/worker/main.js
CHANGED
|
@@ -10,11 +10,9 @@ const diagnosticChannel = require('node:diagnostics_channel')
|
|
|
10
10
|
const { ServerResponse } = require('node:http')
|
|
11
11
|
|
|
12
12
|
const pino = require('pino')
|
|
13
|
-
const { fetch, setGlobalDispatcher,
|
|
13
|
+
const { fetch, setGlobalDispatcher, Agent } = require('undici')
|
|
14
14
|
const { wire } = require('undici-thread-interceptor')
|
|
15
|
-
const undici = require('undici')
|
|
16
15
|
|
|
17
|
-
const RemoteCacheStore = require('./http-cache')
|
|
18
16
|
const { PlatformaticApp } = require('./app')
|
|
19
17
|
const { setupITC } = require('./itc')
|
|
20
18
|
const loadInterceptors = require('./interceptors')
|
|
@@ -92,34 +90,10 @@ async function main () {
|
|
|
92
90
|
}
|
|
93
91
|
}
|
|
94
92
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const poolInterceptors = []
|
|
100
|
-
|
|
101
|
-
if (interceptors.Agent) {
|
|
102
|
-
clientInterceptors.push(...interceptors.Agent)
|
|
103
|
-
poolInterceptors.push(...interceptors.Agent)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (interceptors.Pool) {
|
|
107
|
-
poolInterceptors.push(...interceptors.Pool)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (interceptors.Client) {
|
|
111
|
-
clientInterceptors.push(...interceptors.Client)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
dispatcherOpts.factory = (origin, opts) => {
|
|
115
|
-
return opts && opts.connections === 1
|
|
116
|
-
? new undici.Client(origin, opts).compose(clientInterceptors)
|
|
117
|
-
: new undici.Pool(origin, opts).compose(poolInterceptors)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const globalDispatcher = new Agent(dispatcherOpts)
|
|
122
|
-
.compose(composedInterceptors)
|
|
93
|
+
const globalDispatcher = new Agent({
|
|
94
|
+
...config.undici,
|
|
95
|
+
interceptors
|
|
96
|
+
}).compose(composedInterceptors)
|
|
123
97
|
|
|
124
98
|
setGlobalDispatcher(globalDispatcher)
|
|
125
99
|
|
|
@@ -128,15 +102,6 @@ async function main () {
|
|
|
128
102
|
// TODO: make this configurable
|
|
129
103
|
const threadDispatcher = wire({ port: parentPort, useNetwork: service.useHttp, timeout: 5 * 60 * 1000 })
|
|
130
104
|
|
|
131
|
-
if (config.httpCache) {
|
|
132
|
-
setGlobalDispatcher(
|
|
133
|
-
getGlobalDispatcher().compose(undici.interceptors.cache({
|
|
134
|
-
store: new RemoteCacheStore(),
|
|
135
|
-
methods: config.httpCache.methods ?? ['GET', 'HEAD']
|
|
136
|
-
}))
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
105
|
// If the service is an entrypoint and runtime server config is defined, use it.
|
|
141
106
|
let serverConfig = null
|
|
142
107
|
if (config.server && service.entrypoint) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -35,19 +35,18 @@
|
|
|
35
35
|
"typescript": "^5.5.4",
|
|
36
36
|
"undici-oidc-interceptor": "^0.5.0",
|
|
37
37
|
"why-is-node-running": "^2.2.2",
|
|
38
|
-
"@platformatic/composer": "2.
|
|
39
|
-
"@platformatic/db": "2.
|
|
40
|
-
"@platformatic/
|
|
41
|
-
"@platformatic/
|
|
42
|
-
"@platformatic/
|
|
43
|
-
"@platformatic/sql-mapper": "2.
|
|
38
|
+
"@platformatic/composer": "2.9.0",
|
|
39
|
+
"@platformatic/db": "2.9.0",
|
|
40
|
+
"@platformatic/node": "2.9.0",
|
|
41
|
+
"@platformatic/sql-graphql": "2.9.0",
|
|
42
|
+
"@platformatic/service": "2.9.0",
|
|
43
|
+
"@platformatic/sql-mapper": "2.9.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@fastify/error": "^4.0.0",
|
|
47
47
|
"@fastify/websocket": "^11.0.0",
|
|
48
48
|
"@hapi/topo": "^6.0.2",
|
|
49
49
|
"@platformatic/http-metrics": "^0.2.1",
|
|
50
|
-
"@platformatic/undici-cache-memory": "^0.3.0",
|
|
51
50
|
"@watchable/unpromise": "^1.0.2",
|
|
52
51
|
"boring-name-generator": "^1.0.3",
|
|
53
52
|
"change-case-all": "^2.1.0",
|
|
@@ -69,16 +68,16 @@
|
|
|
69
68
|
"semgrator": "^0.3.0",
|
|
70
69
|
"tail-file-stream": "^0.2.0",
|
|
71
70
|
"thread-cpu-usage": "^0.2.0",
|
|
72
|
-
"undici": "
|
|
71
|
+
"undici": "^6.9.0",
|
|
73
72
|
"undici-thread-interceptor": "^0.7.0",
|
|
74
73
|
"ws": "^8.16.0",
|
|
75
|
-
"@platformatic/basic": "2.
|
|
76
|
-
"@platformatic/config": "2.
|
|
77
|
-
"@platformatic/
|
|
78
|
-
"@platformatic/
|
|
79
|
-
"@platformatic/telemetry": "2.
|
|
80
|
-
"@platformatic/
|
|
81
|
-
"@platformatic/
|
|
74
|
+
"@platformatic/basic": "2.9.0",
|
|
75
|
+
"@platformatic/config": "2.9.0",
|
|
76
|
+
"@platformatic/generators": "2.9.0",
|
|
77
|
+
"@platformatic/itc": "2.9.0",
|
|
78
|
+
"@platformatic/telemetry": "2.9.0",
|
|
79
|
+
"@platformatic/ts-compiler": "2.9.0",
|
|
80
|
+
"@platformatic/utils": "2.9.0"
|
|
82
81
|
},
|
|
83
82
|
"scripts": {
|
|
84
83
|
"test": "npm run lint && borp --concurrency=1 --timeout=300000 && tsd",
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.9.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
@@ -451,35 +451,6 @@
|
|
|
451
451
|
}
|
|
452
452
|
}
|
|
453
453
|
},
|
|
454
|
-
"httpCache": {
|
|
455
|
-
"oneOf": [
|
|
456
|
-
{
|
|
457
|
-
"type": "boolean"
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
"type": "object",
|
|
461
|
-
"properties": {
|
|
462
|
-
"store": {
|
|
463
|
-
"type": "string"
|
|
464
|
-
},
|
|
465
|
-
"methods": {
|
|
466
|
-
"type": "array",
|
|
467
|
-
"items": {
|
|
468
|
-
"type": "string"
|
|
469
|
-
},
|
|
470
|
-
"default": [
|
|
471
|
-
"GET",
|
|
472
|
-
"HEAD"
|
|
473
|
-
],
|
|
474
|
-
"minItems": 1
|
|
475
|
-
},
|
|
476
|
-
"cacheTagsHeader": {
|
|
477
|
-
"type": "string"
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
]
|
|
482
|
-
},
|
|
483
454
|
"watch": {
|
|
484
455
|
"anyOf": [
|
|
485
456
|
{
|
package/lib/shared-http-cache.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { join } = require('node:path')
|
|
4
|
-
const { createRequire } = require('node:module')
|
|
5
|
-
const MemoryCacheStore = require('@platformatic/undici-cache-memory')
|
|
6
|
-
|
|
7
|
-
function createSharedStore (projectDir, httpCacheConfig = {}) {
|
|
8
|
-
const runtimeRequire = createRequire(join(projectDir, 'file'))
|
|
9
|
-
|
|
10
|
-
const { store, ...storeConfig } = httpCacheConfig
|
|
11
|
-
const CacheStore = store ? runtimeRequire(store) : MemoryCacheStore
|
|
12
|
-
|
|
13
|
-
class SharedCacheStore extends CacheStore {
|
|
14
|
-
async getValue (req) {
|
|
15
|
-
const readStream = await this.createReadStream(req)
|
|
16
|
-
if (!readStream) return null
|
|
17
|
-
|
|
18
|
-
let payload = ''
|
|
19
|
-
for await (const chunk of readStream) {
|
|
20
|
-
payload += chunk
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const response = this.#sanitizeResponse(readStream.value)
|
|
24
|
-
return { response, payload }
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
setValue (req, opts, data) {
|
|
28
|
-
const writeStream = this.createWriteStream(req, opts)
|
|
29
|
-
writeStream.write(data)
|
|
30
|
-
writeStream.end()
|
|
31
|
-
return null
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
#sanitizeResponse (response) {
|
|
35
|
-
return {
|
|
36
|
-
...response,
|
|
37
|
-
rawHeaders: response.rawHeaders.map(header => header.toString())
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return new SharedCacheStore(storeConfig)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
module.exports = { createSharedStore }
|
package/lib/worker/http-cache.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Readable, Writable } = require('node:stream')
|
|
4
|
-
const { kITC } = require('./symbols')
|
|
5
|
-
|
|
6
|
-
class RemoteCacheStore {
|
|
7
|
-
get isFull () {
|
|
8
|
-
// TODO: make an itc call to the shared cache when interceptor supports
|
|
9
|
-
// an async isFull method
|
|
10
|
-
return false
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async createReadStream (request) {
|
|
14
|
-
const itc = globalThis[kITC]
|
|
15
|
-
if (!itc) return
|
|
16
|
-
|
|
17
|
-
const cachedValue = await itc.send('getHttpCacheValue', {
|
|
18
|
-
request: this.#sanitizeRequest(request)
|
|
19
|
-
})
|
|
20
|
-
if (!cachedValue) return
|
|
21
|
-
|
|
22
|
-
const readable = new Readable({
|
|
23
|
-
read () {}
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
Object.defineProperty(readable, 'value', {
|
|
27
|
-
get () { return cachedValue.response }
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
readable.push(cachedValue.payload)
|
|
31
|
-
readable.push(null)
|
|
32
|
-
|
|
33
|
-
return readable
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
createWriteStream (request, response) {
|
|
37
|
-
const itc = globalThis[kITC]
|
|
38
|
-
if (!itc) throw new Error('Cannot write to cache without an ITC instance')
|
|
39
|
-
|
|
40
|
-
let payload = ''
|
|
41
|
-
|
|
42
|
-
request = this.#sanitizeRequest(request)
|
|
43
|
-
response = this.#sanitizeResponse(response)
|
|
44
|
-
|
|
45
|
-
return new Writable({
|
|
46
|
-
write (chunk, encoding, callback) {
|
|
47
|
-
payload += chunk
|
|
48
|
-
callback()
|
|
49
|
-
},
|
|
50
|
-
final (callback) {
|
|
51
|
-
itc.send('setHttpCacheValue', { request, response, payload })
|
|
52
|
-
.then(() => callback())
|
|
53
|
-
.catch((err) => callback(err))
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
deleteByOrigin (origin) {
|
|
59
|
-
const itc = globalThis[kITC]
|
|
60
|
-
if (!itc) throw new Error('Cannot delete from cache without an ITC instance')
|
|
61
|
-
|
|
62
|
-
itc.send('deleteHttpCacheValue', { origin })
|
|
63
|
-
// TODO: return a Promise
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
#sanitizeRequest (request) {
|
|
67
|
-
return {
|
|
68
|
-
origin: request.origin,
|
|
69
|
-
method: request.method,
|
|
70
|
-
path: request.path,
|
|
71
|
-
headers: request.headers
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
#sanitizeResponse (response) {
|
|
76
|
-
return {
|
|
77
|
-
...response,
|
|
78
|
-
rawHeaders: response.rawHeaders.map(header => header.toString())
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
module.exports = RemoteCacheStore
|