@platformatic/runtime 2.19.0-alpha.5 → 2.19.0-alpha.7

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 CHANGED
@@ -5,7 +5,7 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export type HttpsSchemasPlatformaticDevPlatformaticRuntime2190Alpha5Json = {
8
+ export type HttpsSchemasPlatformaticDevPlatformaticRuntime2190Alpha7Json = {
9
9
  [k: string]: unknown;
10
10
  } & {
11
11
  $schema?: string;
@@ -133,17 +133,6 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime2190Alpha5Json = {
133
133
  };
134
134
  [k: string]: unknown;
135
135
  };
136
- httpCache?:
137
- | boolean
138
- | {
139
- store?: string;
140
- /**
141
- * @minItems 1
142
- */
143
- methods?: [string, ...string[]];
144
- cacheTagsHeader?: string;
145
- [k: string]: unknown;
146
- };
147
136
  watch?: boolean | string;
148
137
  managementApi?:
149
138
  | boolean
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')
@@ -67,7 +66,6 @@ class Runtime extends EventEmitter {
67
66
  #inspectorServer
68
67
  #workers
69
68
  #restartingWorkers
70
- #sharedHttpCache
71
69
 
72
70
  constructor (configManager, runtimeLogsDir, env) {
73
71
  super()
@@ -87,7 +85,6 @@ class Runtime extends EventEmitter {
87
85
  })
88
86
  this.#status = undefined
89
87
  this.#restartingWorkers = new Map()
90
- this.#sharedHttpCache = null
91
88
  }
92
89
 
93
90
  async init () {
@@ -137,16 +134,26 @@ class Runtime extends EventEmitter {
137
134
 
138
135
  // Recompute the list of services after sorting
139
136
  this.#servicesIds = config.services.map(service => service.id)
137
+
138
+ // When autoloading is disabled, add a warning if a service is defined before its dependencies
139
+ if (!autoloadEnabled) {
140
+ for (let i = 0; i < config.services.length; i++) {
141
+ const current = config.services[i]
142
+
143
+ for (const dep of current.dependencies ?? []) {
144
+ if (config.services.findIndex(s => s.id === dep.id) > i) {
145
+ this.logger.warn(
146
+ `Service "${current.id}" depends on service "${dep.id}", but it is defined and it will be started before it. Please check your configuration file.`
147
+ )
148
+ }
149
+ }
150
+ }
151
+ }
140
152
  } catch (e) {
141
153
  await this.close()
142
154
  throw e
143
155
  }
144
156
 
145
- this.#sharedHttpCache = createSharedStore(
146
- this.#configManager.dirname,
147
- config.httpCache
148
- )
149
-
150
157
  this.#updateStatus('init')
151
158
  }
152
159
 
@@ -275,10 +282,6 @@ class Runtime extends EventEmitter {
275
282
  this.#loggerDestination = null
276
283
  }
277
284
 
278
- if (this.#sharedHttpCache?.close) {
279
- await this.#sharedHttpCache.close()
280
- }
281
-
282
285
  this.#updateStatus('closed')
283
286
  }
284
287
 
@@ -741,23 +744,6 @@ class Runtime extends EventEmitter {
741
744
  return createReadStream(filePath)
742
745
  }
743
746
 
744
- async invalidateHttpCache (options = {}) {
745
- const { keys, tags } = options
746
-
747
- if (!this.#sharedHttpCache) return
748
-
749
- const promises = []
750
- if (keys && keys.length > 0) {
751
- promises.push(this.#sharedHttpCache.deleteKeys(keys))
752
- }
753
-
754
- if (tags && tags.length > 0) {
755
- promises.push(this.#sharedHttpCache.deleteTags(tags))
756
- }
757
-
758
- await Promise.all(promises)
759
- }
760
-
761
747
  async sendCommandToService (id, name, message) {
762
748
  const service = await this.#getServiceById(id)
763
749
 
@@ -795,7 +781,7 @@ class Runtime extends EventEmitter {
795
781
  }
796
782
 
797
783
  async #setupWorker (config, serviceConfig, workersCount, serviceId, index) {
798
- const { autoload, restartOnError } = config
784
+ const { restartOnError } = config
799
785
  const workerId = `${serviceId}:${index}`
800
786
 
801
787
  const { port1: loggerDestination, port2: loggingPort } = new MessageChannel()
@@ -914,18 +900,9 @@ class Runtime extends EventEmitter {
914
900
  port: worker,
915
901
  handlers: {
916
902
  getServiceMeta: this.getServiceMeta.bind(this),
917
- listServices: () => this.#servicesIds,
918
- getServices: this.getServices.bind(this),
919
- getHttpCacheValue: opts => this.#sharedHttpCache.getValue(opts.request),
920
- setHttpCacheValue: opts => this.#sharedHttpCache.setValue(
921
- opts.request,
922
- opts.response,
923
- opts.payload
924
- ),
925
- deleteHttpCacheValue: opts => this.#sharedHttpCache.delete(
926
- opts.request
927
- ),
928
- invalidateHttpCache: opts => this.invalidateHttpCache(opts),
903
+ listServices: () => {
904
+ return this.#servicesIds
905
+ }
929
906
  }
930
907
  })
931
908
  worker[kITC].listen()
@@ -969,12 +946,10 @@ class Runtime extends EventEmitter {
969
946
  // Store dependencies
970
947
  const [{ dependencies }] = await waitEventFromITC(worker, 'init')
971
948
 
972
- if (autoload) {
973
- serviceConfig.dependencies = dependencies
974
- for (const { envVar, url } of dependencies) {
975
- if (envVar) {
976
- serviceConfig.localServiceEnvVars.set(envVar, url)
977
- }
949
+ serviceConfig.dependencies = dependencies
950
+ for (const { envVar, url } of dependencies) {
951
+ if (envVar) {
952
+ serviceConfig.localServiceEnvVars.set(envVar, url)
978
953
  }
979
954
  }
980
955
 
package/lib/schema.js CHANGED
@@ -194,32 +194,6 @@ const platformaticRuntimeSchema = {
194
194
  }
195
195
  }
196
196
  },
197
- httpCache: {
198
- oneOf: [
199
- {
200
- type: 'boolean'
201
- },
202
- {
203
- type: 'object',
204
- properties: {
205
- store: {
206
- type: 'string'
207
- },
208
- methods: {
209
- type: 'array',
210
- items: {
211
- type: 'string'
212
- },
213
- default: ['GET', 'HEAD'],
214
- minItems: 1
215
- },
216
- cacheTagsHeader: {
217
- type: 'string'
218
- }
219
- }
220
- }
221
- ]
222
- },
223
197
  watch: {
224
198
  anyOf: [
225
199
  {
@@ -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, getGlobalDispatcher, Agent } = require('undici')
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')
@@ -94,50 +92,22 @@ async function main () {
94
92
  }
95
93
  }
96
94
 
97
- const dispatcherOpts = { ...config.undici }
98
-
99
- if (Object.keys(interceptors).length > 0) {
100
- const clientInterceptors = []
101
- const poolInterceptors = []
102
-
103
- if (interceptors.Agent) {
104
- clientInterceptors.push(...interceptors.Agent)
105
- poolInterceptors.push(...interceptors.Agent)
106
- }
107
-
108
- if (interceptors.Pool) {
109
- poolInterceptors.push(...interceptors.Pool)
110
- }
111
-
112
- if (interceptors.Client) {
113
- clientInterceptors.push(...interceptors.Client)
114
- }
115
-
116
- dispatcherOpts.factory = (origin, opts) => {
117
- return opts && opts.connections === 1
118
- ? new undici.Client(origin, opts).compose(clientInterceptors)
119
- : new undici.Pool(origin, opts).compose(poolInterceptors)
120
- }
121
- }
122
-
123
- const globalDispatcher = new Agent(dispatcherOpts)
124
- .compose(composedInterceptors)
95
+ const globalDispatcher = new Agent({
96
+ ...config.undici,
97
+ interceptors
98
+ }).compose(composedInterceptors)
125
99
 
126
100
  setGlobalDispatcher(globalDispatcher)
127
101
 
128
102
  const { telemetry } = service
129
103
  const hooks = telemetry ? createTelemetryThreadInterceptorHooks() : {}
130
104
  // Setup mesh networker
131
- const threadDispatcher = wire({ port: parentPort, useNetwork: service.useHttp, timeout: config.serviceTimeout, ...hooks })
132
-
133
- if (config.httpCache) {
134
- setGlobalDispatcher(
135
- getGlobalDispatcher().compose(undici.interceptors.cache({
136
- store: new RemoteCacheStore(),
137
- methods: config.httpCache.methods ?? ['GET', 'HEAD']
138
- }))
139
- )
140
- }
105
+ const threadDispatcher = wire({
106
+ port: parentPort,
107
+ useNetwork: service.useHttp,
108
+ timeout: config.serviceTimeout,
109
+ ...hooks
110
+ })
141
111
 
142
112
  // If the service is an entrypoint and runtime server config is defined, use it.
143
113
  let serverConfig = null
@@ -185,7 +155,7 @@ async function main () {
185
155
 
186
156
  if (service.entrypoint && config.basePath) {
187
157
  const meta = await app.stackable.getMeta()
188
- if (!meta.wantsAbsoluteUrls) {
158
+ if (!meta.composer.wantsAbsoluteUrls) {
189
159
  stripBasePath(config.basePath)
190
160
  }
191
161
  }
@@ -195,7 +165,7 @@ async function main () {
195
165
  globalThis[kITC] = itc
196
166
 
197
167
  // Get the dependencies
198
- const dependencies = config.autoload ? await app.getBootstrapDependencies() : []
168
+ const dependencies = await app.getBootstrapDependencies()
199
169
  itc.notify('init', { dependencies })
200
170
  }
201
171
 
@@ -226,10 +196,7 @@ function stripBasePath (basePath) {
226
196
 
227
197
  if (headers) {
228
198
  for (const key in headers) {
229
- if (
230
- key.toLowerCase() === 'location' &&
231
- !headers[key].startsWith(basePath)
232
- ) {
199
+ if (key.toLowerCase() === 'location' && !headers[key].startsWith(basePath)) {
233
200
  headers[key] = basePath + headers[key]
234
201
  }
235
202
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/runtime",
3
- "version": "2.19.0-alpha.5",
3
+ "version": "2.19.0-alpha.7",
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.19.0-alpha.5",
39
- "@platformatic/db": "2.19.0-alpha.5",
40
- "@platformatic/node": "2.19.0-alpha.5",
41
- "@platformatic/sql-graphql": "2.19.0-alpha.5",
42
- "@platformatic/service": "2.19.0-alpha.5",
43
- "@platformatic/sql-mapper": "2.19.0-alpha.5"
38
+ "@platformatic/composer": "2.19.0-alpha.7",
39
+ "@platformatic/db": "2.19.0-alpha.7",
40
+ "@platformatic/node": "2.19.0-alpha.7",
41
+ "@platformatic/service": "2.19.0-alpha.7",
42
+ "@platformatic/sql-graphql": "2.19.0-alpha.7",
43
+ "@platformatic/sql-mapper": "2.19.0-alpha.7"
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.8.0",
51
50
  "@watchable/unpromise": "^1.0.2",
52
51
  "boring-name-generator": "^1.0.3",
53
52
  "change-case-all": "^2.1.0",
@@ -68,17 +67,16 @@
68
67
  "prom-client": "^15.1.2",
69
68
  "semgrator": "^0.3.0",
70
69
  "tail-file-stream": "^0.2.0",
71
- "thread-cpu-usage": "^0.2.0",
72
- "undici": "7.0.0",
73
- "undici-thread-interceptor": "^0.10.0",
70
+ "undici": "^6.9.0",
71
+ "undici-thread-interceptor": "^0.9.0",
74
72
  "ws": "^8.16.0",
75
- "@platformatic/basic": "2.19.0-alpha.5",
76
- "@platformatic/config": "2.19.0-alpha.5",
77
- "@platformatic/generators": "2.19.0-alpha.5",
78
- "@platformatic/itc": "2.19.0-alpha.5",
79
- "@platformatic/telemetry": "2.19.0-alpha.5",
80
- "@platformatic/utils": "2.19.0-alpha.5",
81
- "@platformatic/ts-compiler": "2.19.0-alpha.5"
73
+ "@platformatic/basic": "2.19.0-alpha.7",
74
+ "@platformatic/generators": "2.19.0-alpha.7",
75
+ "@platformatic/ts-compiler": "2.19.0-alpha.7",
76
+ "@platformatic/utils": "2.19.0-alpha.7",
77
+ "@platformatic/config": "2.19.0-alpha.7",
78
+ "@platformatic/itc": "2.19.0-alpha.7",
79
+ "@platformatic/telemetry": "2.19.0-alpha.7"
82
80
  },
83
81
  "scripts": {
84
82
  "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.19.0-alpha.5.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.19.0-alpha.7.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "type": "object",
5
5
  "properties": {
@@ -840,35 +840,6 @@
840
840
  }
841
841
  }
842
842
  },
843
- "httpCache": {
844
- "oneOf": [
845
- {
846
- "type": "boolean"
847
- },
848
- {
849
- "type": "object",
850
- "properties": {
851
- "store": {
852
- "type": "string"
853
- },
854
- "methods": {
855
- "type": "array",
856
- "items": {
857
- "type": "string"
858
- },
859
- "default": [
860
- "GET",
861
- "HEAD"
862
- ],
863
- "minItems": 1
864
- },
865
- "cacheTagsHeader": {
866
- "type": "string"
867
- }
868
- }
869
- }
870
- ]
871
- },
872
843
  "watch": {
873
844
  "anyOf": [
874
845
  {
@@ -1,39 +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 cachedValue = await this.get(req)
16
- if (!cachedValue) return null
17
-
18
- const { body, ...response } = cachedValue
19
-
20
- let payload = ''
21
- for await (const chunk of body) {
22
- payload += chunk
23
- }
24
-
25
- return { response, payload }
26
- }
27
-
28
- setValue (req, opts, data) {
29
- const writeStream = this.createWriteStream(req, opts)
30
- writeStream.write(data)
31
- writeStream.end()
32
- return null
33
- }
34
- }
35
-
36
- return new SharedCacheStore(storeConfig)
37
- }
38
-
39
- module.exports = { createSharedStore }
@@ -1,73 +0,0 @@
1
- 'use strict'
2
-
3
- const { Readable, Writable } = require('node:stream')
4
- const { kITC } = require('./symbols')
5
-
6
- class RemoteCacheStore {
7
- async get (request) {
8
- const itc = globalThis[kITC]
9
- if (!itc) return
10
-
11
- const cachedValue = await itc.send('getHttpCacheValue', {
12
- request: this.#sanitizeRequest(request)
13
- })
14
- if (!cachedValue) return
15
-
16
- const readable = new Readable({
17
- read () {}
18
- })
19
-
20
- Object.defineProperty(readable, 'value', {
21
- get () { return cachedValue.response }
22
- })
23
-
24
- readable.push(cachedValue.payload)
25
- readable.push(null)
26
-
27
- return {
28
- ...cachedValue.response,
29
- body: readable
30
- }
31
- }
32
-
33
- createWriteStream (request, response) {
34
- const itc = globalThis[kITC]
35
- if (!itc) throw new Error('Cannot write to cache without an ITC instance')
36
-
37
- let payload = ''
38
-
39
- request = this.#sanitizeRequest(request)
40
-
41
- return new Writable({
42
- write (chunk, encoding, callback) {
43
- payload += chunk
44
- callback()
45
- },
46
- final (callback) {
47
- itc.send('setHttpCacheValue', { request, response, payload })
48
- .then(() => callback())
49
- .catch((err) => callback(err))
50
- }
51
- })
52
- }
53
-
54
- delete (request) {
55
- const itc = globalThis[kITC]
56
- if (!itc) throw new Error('Cannot delete from cache without an ITC instance')
57
-
58
- request = this.#sanitizeRequest(request)
59
- itc.send('deleteHttpCacheValue', { request })
60
- // TODO: return a Promise
61
- }
62
-
63
- #sanitizeRequest (request) {
64
- return {
65
- origin: request.origin,
66
- method: request.method,
67
- path: request.path,
68
- headers: request.headers
69
- }
70
- }
71
- }
72
-
73
- module.exports = RemoteCacheStore