@platformatic/basic 3.29.1 → 3.31.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 +25 -1
- package/lib/capability.js +37 -3
- package/lib/worker/child-process.js +68 -3
- package/package.json +6 -6
- package/schema.json +67 -5
package/config.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface PlatformaticBasicConfig {
|
|
|
31
31
|
};
|
|
32
32
|
workersRestartDelay?: number | string;
|
|
33
33
|
logger?: {
|
|
34
|
-
level
|
|
34
|
+
level?: (
|
|
35
35
|
| ("fatal" | "error" | "warn" | "info" | "debug" | "trace" | "silent")
|
|
36
36
|
| {
|
|
37
37
|
[k: string]: unknown;
|
|
@@ -414,6 +414,18 @@ export interface PlatformaticBasicConfig {
|
|
|
414
414
|
[k: string]: string | [string, ...string[]];
|
|
415
415
|
};
|
|
416
416
|
};
|
|
417
|
+
compileCache?:
|
|
418
|
+
| boolean
|
|
419
|
+
| {
|
|
420
|
+
/**
|
|
421
|
+
* Enable Node.js module compile cache for faster startup
|
|
422
|
+
*/
|
|
423
|
+
enabled?: boolean;
|
|
424
|
+
/**
|
|
425
|
+
* Directory to store compile cache. Defaults to .plt/compile-cache in app root
|
|
426
|
+
*/
|
|
427
|
+
directory?: string;
|
|
428
|
+
};
|
|
417
429
|
application?: {
|
|
418
430
|
reuseTcpPorts?: boolean;
|
|
419
431
|
workers?:
|
|
@@ -472,6 +484,18 @@ export interface PlatformaticBasicConfig {
|
|
|
472
484
|
)[];
|
|
473
485
|
[k: string]: unknown;
|
|
474
486
|
};
|
|
487
|
+
compileCache?:
|
|
488
|
+
| boolean
|
|
489
|
+
| {
|
|
490
|
+
/**
|
|
491
|
+
* Enable Node.js module compile cache for faster startup
|
|
492
|
+
*/
|
|
493
|
+
enabled?: boolean;
|
|
494
|
+
/**
|
|
495
|
+
* Directory to store compile cache. Defaults to .plt/compile-cache in app root
|
|
496
|
+
*/
|
|
497
|
+
directory?: string;
|
|
498
|
+
};
|
|
475
499
|
};
|
|
476
500
|
};
|
|
477
501
|
[k: string]: unknown;
|
package/lib/capability.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
kMetadata,
|
|
8
8
|
kTimeout
|
|
9
9
|
} from '@platformatic/foundation'
|
|
10
|
-
import { client,
|
|
10
|
+
import { clearRegistry, client, collectThreadMetrics, ensureMetricsGroup, setupOtlpExporter } from '@platformatic/metrics'
|
|
11
11
|
import { parseCommandString } from 'execa'
|
|
12
12
|
import { spawn } from 'node:child_process'
|
|
13
13
|
import { tracingChannel } from 'node:diagnostics_channel'
|
|
@@ -155,6 +155,37 @@ export class BaseCapability extends EventEmitter {
|
|
|
155
155
|
// No-op by default
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
async updateMetricsConfig (metricsConfig) {
|
|
159
|
+
// Transform applicationLabel to idLabel (same transformation as in worker/main.js)
|
|
160
|
+
const normalizedConfig = {
|
|
161
|
+
...metricsConfig,
|
|
162
|
+
idLabel: metricsConfig.applicationLabel || 'applicationId'
|
|
163
|
+
}
|
|
164
|
+
this.context.metricsConfig = normalizedConfig
|
|
165
|
+
|
|
166
|
+
// If running in subprocess mode, send the update to the child process
|
|
167
|
+
if (this.childManager && this.clientWs) {
|
|
168
|
+
await this.childManager.send(this.clientWs, 'updateMetricsConfig', {
|
|
169
|
+
applicationId: this.applicationId,
|
|
170
|
+
workerId: this.workerId,
|
|
171
|
+
metricsConfig: normalizedConfig
|
|
172
|
+
})
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (this.metricsRegistry) {
|
|
177
|
+
// We must clear the registry to stop prom-client from collecting metrics in the background,
|
|
178
|
+
// and because prom-client doesn't support changing labels on existing metrics.
|
|
179
|
+
// This will lose all previously collected metrics.
|
|
180
|
+
clearRegistry(this.metricsRegistry)
|
|
181
|
+
|
|
182
|
+
if (metricsConfig.enabled !== false) {
|
|
183
|
+
this.#metricsCollected = false
|
|
184
|
+
await this._collectMetrics()
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
158
189
|
start () {
|
|
159
190
|
throw new Error('BaseCapability.start must be overriden by the subclasses')
|
|
160
191
|
}
|
|
@@ -547,7 +578,8 @@ export class BaseCapability extends EventEmitter {
|
|
|
547
578
|
backlog: this.serverConfig.backlog
|
|
548
579
|
}
|
|
549
580
|
: {},
|
|
550
|
-
telemetryConfig: this.telemetryConfig
|
|
581
|
+
telemetryConfig: this.telemetryConfig,
|
|
582
|
+
compileCache: this.config.compileCache ?? this.runtimeConfig?.compileCache
|
|
551
583
|
}
|
|
552
584
|
}
|
|
553
585
|
|
|
@@ -708,7 +740,9 @@ export class BaseCapability extends EventEmitter {
|
|
|
708
740
|
return
|
|
709
741
|
}
|
|
710
742
|
|
|
711
|
-
|
|
743
|
+
// Use thread-specific metrics collection - process-level metrics are collected
|
|
744
|
+
// by the main runtime thread and duplicated with worker labels
|
|
745
|
+
await collectThreadMetrics(this.applicationId, this.workerId, metricsConfig, this.metricsRegistry)
|
|
712
746
|
}
|
|
713
747
|
|
|
714
748
|
#setHttpCacheMetrics () {
|
|
@@ -5,14 +5,15 @@ import {
|
|
|
5
5
|
ensureLoggableError
|
|
6
6
|
} from '@platformatic/foundation'
|
|
7
7
|
import { ITC } from '@platformatic/itc/lib/index.js'
|
|
8
|
-
import { client,
|
|
8
|
+
import { clearRegistry, client, collectThreadMetrics } from '@platformatic/metrics'
|
|
9
9
|
import diagnosticChannel, { tracingChannel } from 'node:diagnostics_channel'
|
|
10
10
|
import { EventEmitter, once } from 'node:events'
|
|
11
11
|
import { readFile } from 'node:fs/promises'
|
|
12
12
|
import { ServerResponse } from 'node:http'
|
|
13
13
|
import { register } from 'node:module'
|
|
14
14
|
import { hostname, platform, tmpdir } from 'node:os'
|
|
15
|
-
import { basename, resolve } from 'node:path'
|
|
15
|
+
import { basename, join, resolve } from 'node:path'
|
|
16
|
+
import { fileURLToPath } from 'node:url'
|
|
16
17
|
import pino from 'pino'
|
|
17
18
|
import { Agent, Pool, setGlobalDispatcher } from 'undici'
|
|
18
19
|
import { WebSocket } from 'ws'
|
|
@@ -84,6 +85,9 @@ export class ChildProcess extends ITC {
|
|
|
84
85
|
collectMetrics: (...args) => {
|
|
85
86
|
return this.#collectMetrics(...args)
|
|
86
87
|
},
|
|
88
|
+
updateMetricsConfig: (...args) => {
|
|
89
|
+
return this.#updateMetricsConfig(...args)
|
|
90
|
+
},
|
|
87
91
|
getMetrics: (...args) => {
|
|
88
92
|
return this.#getMetrics(...args)
|
|
89
93
|
},
|
|
@@ -217,10 +221,23 @@ export class ChildProcess extends ITC {
|
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
async #collectMetrics ({ applicationId, workerId, metricsConfig }) {
|
|
220
|
-
|
|
224
|
+
// Use thread-specific metrics collection - process-level metrics are collected
|
|
225
|
+
// by the main runtime thread and duplicated with worker labels
|
|
226
|
+
await collectThreadMetrics(applicationId, workerId, metricsConfig, this.#metricsRegistry)
|
|
221
227
|
this.#setHttpCacheMetrics()
|
|
222
228
|
}
|
|
223
229
|
|
|
230
|
+
async #updateMetricsConfig ({ applicationId, workerId, metricsConfig }) {
|
|
231
|
+
clearRegistry(this.#metricsRegistry)
|
|
232
|
+
|
|
233
|
+
if (metricsConfig.enabled !== false) {
|
|
234
|
+
// Use thread-specific metrics collection - process-level metrics are collected
|
|
235
|
+
// by the main runtime thread and duplicated with worker labels
|
|
236
|
+
await collectThreadMetrics(applicationId, workerId, metricsConfig, this.#metricsRegistry)
|
|
237
|
+
this.#setHttpCacheMetrics()
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
224
241
|
#setHttpCacheMetrics () {
|
|
225
242
|
const { client, registry } = globalThis.platformatic.prometheus
|
|
226
243
|
|
|
@@ -491,12 +508,60 @@ function stripBasePath (basePath) {
|
|
|
491
508
|
}
|
|
492
509
|
}
|
|
493
510
|
|
|
511
|
+
// Enable compile cache if configured (Node.js 22.1.0+)
|
|
512
|
+
async function setupCompileCache (contextData) {
|
|
513
|
+
const config = contextData?.compileCache
|
|
514
|
+
|
|
515
|
+
// Normalize boolean shorthand
|
|
516
|
+
const normalizeConfig = cfg => {
|
|
517
|
+
if (cfg === true) return { enabled: true }
|
|
518
|
+
if (cfg === false) return { enabled: false }
|
|
519
|
+
return cfg
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const normalizedConfig = normalizeConfig(config)
|
|
523
|
+
if (!normalizedConfig?.enabled) {
|
|
524
|
+
return
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Check if API is available (Node.js 22.1.0+)
|
|
528
|
+
let moduleApi
|
|
529
|
+
try {
|
|
530
|
+
moduleApi = await import('node:module')
|
|
531
|
+
if (typeof moduleApi.enableCompileCache !== 'function') {
|
|
532
|
+
return
|
|
533
|
+
}
|
|
534
|
+
} catch {
|
|
535
|
+
return
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Use root from context data (capability's this.root as URL)
|
|
539
|
+
const root = contextData?.root ? fileURLToPath(contextData.root) : null
|
|
540
|
+
if (!root) {
|
|
541
|
+
return
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const cacheDir =
|
|
545
|
+
typeof normalizedConfig === 'object' && normalizedConfig.directory
|
|
546
|
+
? normalizedConfig.directory
|
|
547
|
+
: join(root, '.plt', 'compile-cache')
|
|
548
|
+
|
|
549
|
+
try {
|
|
550
|
+
moduleApi.enableCompileCache(cacheDir)
|
|
551
|
+
} catch {
|
|
552
|
+
// Silently ignore - cache is optional optimization
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
494
556
|
async function main () {
|
|
495
557
|
const executable = basename(process.argv[1] ?? '')
|
|
496
558
|
|
|
497
559
|
const dataPath = resolve(tmpdir(), 'platformatic', 'runtimes', `${process.env.PLT_MANAGER_ID}.json`)
|
|
498
560
|
const { data, loader, scripts } = JSON.parse(await readFile(dataPath))
|
|
499
561
|
|
|
562
|
+
// Enable compile cache early before loading user modules
|
|
563
|
+
await setupCompileCache(data)
|
|
564
|
+
|
|
500
565
|
globalThis.platformatic = Object.assign(globalThis.platformatic ?? {}, data)
|
|
501
566
|
globalThis.platformatic.events = new ForwardingEventEmitter()
|
|
502
567
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/basic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.31.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -25,16 +25,16 @@
|
|
|
25
25
|
"split2": "^4.2.0",
|
|
26
26
|
"undici": "^7.0.0",
|
|
27
27
|
"ws": "^8.18.0",
|
|
28
|
-
"@platformatic/foundation": "3.
|
|
29
|
-
"@platformatic/itc": "3.
|
|
30
|
-
"@platformatic/
|
|
31
|
-
"@platformatic/
|
|
28
|
+
"@platformatic/foundation": "3.31.0",
|
|
29
|
+
"@platformatic/itc": "3.31.0",
|
|
30
|
+
"@platformatic/metrics": "3.31.0",
|
|
31
|
+
"@platformatic/telemetry": "3.31.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"cleaner-spec-reporter": "^0.5.0",
|
|
35
35
|
"eslint": "9",
|
|
36
36
|
"express": "^4.19.2",
|
|
37
|
-
"fastify": "^5.
|
|
37
|
+
"fastify": "^5.7.0",
|
|
38
38
|
"get-port": "^7.1.0",
|
|
39
39
|
"json-schema-to-typescript": "^15.0.0",
|
|
40
40
|
"neostandard": "^0.12.0",
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/basic/3.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/basic/3.31.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Basic Config",
|
|
5
5
|
"type": "object",
|
|
@@ -336,6 +336,28 @@
|
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
|
+
},
|
|
340
|
+
"compileCache": {
|
|
341
|
+
"anyOf": [
|
|
342
|
+
{
|
|
343
|
+
"type": "boolean"
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
"type": "object",
|
|
347
|
+
"properties": {
|
|
348
|
+
"enabled": {
|
|
349
|
+
"type": "boolean",
|
|
350
|
+
"default": true,
|
|
351
|
+
"description": "Enable Node.js module compile cache for faster startup"
|
|
352
|
+
},
|
|
353
|
+
"directory": {
|
|
354
|
+
"type": "string",
|
|
355
|
+
"description": "Directory to store compile cache. Defaults to .plt/compile-cache in app root"
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
"additionalProperties": false
|
|
359
|
+
}
|
|
360
|
+
]
|
|
339
361
|
}
|
|
340
362
|
}
|
|
341
363
|
}
|
|
@@ -415,7 +437,6 @@
|
|
|
415
437
|
"properties": {
|
|
416
438
|
"level": {
|
|
417
439
|
"type": "string",
|
|
418
|
-
"default": "info",
|
|
419
440
|
"oneOf": [
|
|
420
441
|
{
|
|
421
442
|
"enum": [
|
|
@@ -558,9 +579,6 @@
|
|
|
558
579
|
"additionalProperties": true
|
|
559
580
|
}
|
|
560
581
|
},
|
|
561
|
-
"required": [
|
|
562
|
-
"level"
|
|
563
|
-
],
|
|
564
582
|
"default": {},
|
|
565
583
|
"additionalProperties": true
|
|
566
584
|
},
|
|
@@ -1602,6 +1620,28 @@
|
|
|
1602
1620
|
],
|
|
1603
1621
|
"additionalProperties": false
|
|
1604
1622
|
},
|
|
1623
|
+
"compileCache": {
|
|
1624
|
+
"anyOf": [
|
|
1625
|
+
{
|
|
1626
|
+
"type": "boolean"
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
"type": "object",
|
|
1630
|
+
"properties": {
|
|
1631
|
+
"enabled": {
|
|
1632
|
+
"type": "boolean",
|
|
1633
|
+
"default": true,
|
|
1634
|
+
"description": "Enable Node.js module compile cache for faster startup"
|
|
1635
|
+
},
|
|
1636
|
+
"directory": {
|
|
1637
|
+
"type": "string",
|
|
1638
|
+
"description": "Directory to store compile cache. Defaults to .plt/compile-cache in app root"
|
|
1639
|
+
}
|
|
1640
|
+
},
|
|
1641
|
+
"additionalProperties": false
|
|
1642
|
+
}
|
|
1643
|
+
]
|
|
1644
|
+
},
|
|
1605
1645
|
"application": {
|
|
1606
1646
|
"type": "object",
|
|
1607
1647
|
"properties": {
|
|
@@ -1866,6 +1906,28 @@
|
|
|
1866
1906
|
}
|
|
1867
1907
|
}
|
|
1868
1908
|
}
|
|
1909
|
+
},
|
|
1910
|
+
"compileCache": {
|
|
1911
|
+
"anyOf": [
|
|
1912
|
+
{
|
|
1913
|
+
"type": "boolean"
|
|
1914
|
+
},
|
|
1915
|
+
{
|
|
1916
|
+
"type": "object",
|
|
1917
|
+
"properties": {
|
|
1918
|
+
"enabled": {
|
|
1919
|
+
"type": "boolean",
|
|
1920
|
+
"default": true,
|
|
1921
|
+
"description": "Enable Node.js module compile cache for faster startup"
|
|
1922
|
+
},
|
|
1923
|
+
"directory": {
|
|
1924
|
+
"type": "string",
|
|
1925
|
+
"description": "Directory to store compile cache. Defaults to .plt/compile-cache in app root"
|
|
1926
|
+
}
|
|
1927
|
+
},
|
|
1928
|
+
"additionalProperties": false
|
|
1929
|
+
}
|
|
1930
|
+
]
|
|
1869
1931
|
}
|
|
1870
1932
|
},
|
|
1871
1933
|
"additionalProperties": false
|