@platformatic/basic 2.37.0 → 2.38.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/base.js +26 -52
- package/lib/worker/child-manager.js +1 -15
- package/lib/worker/child-process.js +5 -13
- package/package.json +6 -6
- package/schema.json +1 -1
package/lib/base.js
CHANGED
|
@@ -8,7 +8,6 @@ import { hostname, platform } from 'node:os'
|
|
|
8
8
|
import { pathToFileURL } from 'node:url'
|
|
9
9
|
import { workerData } from 'node:worker_threads'
|
|
10
10
|
import pino from 'pino'
|
|
11
|
-
import split2 from 'split2'
|
|
12
11
|
import { NonZeroExitCode } from './errors.js'
|
|
13
12
|
import { cleanBasePath } from './utils.js'
|
|
14
13
|
import { ChildManager } from './worker/child-manager.js'
|
|
@@ -21,7 +20,7 @@ export class BaseStackable {
|
|
|
21
20
|
#subprocessStarted
|
|
22
21
|
#metricsCollected
|
|
23
22
|
|
|
24
|
-
constructor (type, version, options, root, configManager) {
|
|
23
|
+
constructor (type, version, options, root, configManager, standardStreams = {}) {
|
|
25
24
|
options.context.worker ??= { count: 1, index: 0 }
|
|
26
25
|
|
|
27
26
|
this.type = type
|
|
@@ -45,6 +44,8 @@ export class BaseStackable {
|
|
|
45
44
|
this.endHttpTimer = null
|
|
46
45
|
this.clientWs = null
|
|
47
46
|
this.runtimeConfig = deepmerge(options.context?.runtimeConfig ?? {}, workerData?.config ?? {})
|
|
47
|
+
this.stdout = standardStreams?.stdout ?? process.stdout
|
|
48
|
+
this.stderr = standardStreams?.stderr ?? process.stderr
|
|
48
49
|
|
|
49
50
|
// Setup the logger
|
|
50
51
|
const pinoOptions = {
|
|
@@ -59,7 +60,7 @@ export class BaseStackable {
|
|
|
59
60
|
pinoOptions.base = { pid: process.pid, hostname: hostname(), worker: this.workerId }
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
this.logger = pino(pinoOptions)
|
|
63
|
+
this.logger = pino(pinoOptions, standardStreams?.stdout)
|
|
63
64
|
|
|
64
65
|
// Setup globals
|
|
65
66
|
this.registerGlobals({
|
|
@@ -182,27 +183,7 @@ export class BaseStackable {
|
|
|
182
183
|
try {
|
|
183
184
|
await this.childManager?.inject()
|
|
184
185
|
|
|
185
|
-
const subprocess = this.spawn(command)
|
|
186
|
-
subprocess.stdout.setEncoding('utf8')
|
|
187
|
-
subprocess.stderr.setEncoding('utf8')
|
|
188
|
-
|
|
189
|
-
// Wait for the process to be started
|
|
190
|
-
await new Promise((resolve, reject) => {
|
|
191
|
-
subprocess.on('spawn', resolve)
|
|
192
|
-
subprocess.on('error', reject)
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
// Route anything not catched by child process logger to the logger manually
|
|
196
|
-
/* c8 ignore next 3 */
|
|
197
|
-
subprocess.stdout.pipe(split2()).on('data', line => {
|
|
198
|
-
this.logger.info(line)
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
/* c8 ignore next 3 */
|
|
202
|
-
subprocess.stderr.pipe(split2()).on('data', line => {
|
|
203
|
-
this.logger.error(line)
|
|
204
|
-
})
|
|
205
|
-
|
|
186
|
+
const subprocess = await this.spawn(command)
|
|
206
187
|
const [exitCode] = await once(subprocess, 'exit')
|
|
207
188
|
|
|
208
189
|
if (exitCode !== 0) {
|
|
@@ -250,28 +231,7 @@ export class BaseStackable {
|
|
|
250
231
|
|
|
251
232
|
try {
|
|
252
233
|
await this.childManager.inject()
|
|
253
|
-
|
|
254
|
-
this.subprocess = this.spawn(command)
|
|
255
|
-
this.subprocess.stdout.setEncoding('utf8')
|
|
256
|
-
this.subprocess.stderr.setEncoding('utf8')
|
|
257
|
-
|
|
258
|
-
// Route anything not catched by child process logger to the logger manually
|
|
259
|
-
/* c8 ignore next 3 */
|
|
260
|
-
this.subprocess.stdout.pipe(split2()).on('data', line => {
|
|
261
|
-
this.logger.info(line)
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
/* c8 ignore next 3 */
|
|
265
|
-
this.subprocess.stderr.pipe(split2()).on('data', line => {
|
|
266
|
-
this.logger.error(line)
|
|
267
|
-
})
|
|
268
|
-
|
|
269
|
-
// Wait for the process to be started
|
|
270
|
-
await new Promise((resolve, reject) => {
|
|
271
|
-
this.subprocess.on('spawn', resolve)
|
|
272
|
-
this.subprocess.on('error', reject)
|
|
273
|
-
})
|
|
274
|
-
|
|
234
|
+
this.subprocess = await this.spawn(command)
|
|
275
235
|
this.#subprocessStarted = true
|
|
276
236
|
} catch (e) {
|
|
277
237
|
this.childManager.close()
|
|
@@ -327,13 +287,28 @@ export class BaseStackable {
|
|
|
327
287
|
return this.childManager
|
|
328
288
|
}
|
|
329
289
|
|
|
330
|
-
spawn (command) {
|
|
290
|
+
async spawn (command) {
|
|
331
291
|
const [executable, ...args] = parseCommandString(command)
|
|
332
292
|
|
|
333
293
|
/* c8 ignore next 3 */
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
294
|
+
const subprocess =
|
|
295
|
+
platform() === 'win32'
|
|
296
|
+
? spawn(command, { cwd: this.root, shell: true, windowsVerbatimArguments: true })
|
|
297
|
+
: spawn(executable, args, { cwd: this.root })
|
|
298
|
+
|
|
299
|
+
subprocess.stdout.setEncoding('utf8')
|
|
300
|
+
subprocess.stderr.setEncoding('utf8')
|
|
301
|
+
|
|
302
|
+
subprocess.stdout.pipe(this.stdout, { end: false })
|
|
303
|
+
subprocess.stderr.pipe(this.stderr, { end: false })
|
|
304
|
+
|
|
305
|
+
// Wait for the process to be started
|
|
306
|
+
await new Promise((resolve, reject) => {
|
|
307
|
+
subprocess.on('spawn', resolve)
|
|
308
|
+
subprocess.on('error', reject)
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
return subprocess
|
|
337
312
|
}
|
|
338
313
|
|
|
339
314
|
async _collectMetrics () {
|
|
@@ -437,8 +412,7 @@ export class BaseStackable {
|
|
|
437
412
|
/* c8 ignore next 2 */
|
|
438
413
|
port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
|
|
439
414
|
host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true,
|
|
440
|
-
telemetryConfig: this.telemetryConfig
|
|
441
|
-
interceptLogging: typeof workerData?.loggingPort !== 'undefined'
|
|
415
|
+
telemetryConfig: this.telemetryConfig
|
|
442
416
|
}
|
|
443
417
|
}
|
|
444
418
|
}
|
|
@@ -7,7 +7,6 @@ import { register } from 'node:module'
|
|
|
7
7
|
import { platform, tmpdir } from 'node:os'
|
|
8
8
|
import { dirname, join, resolve } from 'node:path'
|
|
9
9
|
import { pathToFileURL } from 'node:url'
|
|
10
|
-
import { workerData } from 'node:worker_threads'
|
|
11
10
|
import { request } from 'undici'
|
|
12
11
|
import { WebSocketServer } from 'ws'
|
|
13
12
|
import { exitCodes } from '../errors.js'
|
|
@@ -60,16 +59,8 @@ export class ChildManager extends ITC {
|
|
|
60
59
|
scripts ??= []
|
|
61
60
|
|
|
62
61
|
super({
|
|
63
|
-
name: 'child-manager',
|
|
64
62
|
...itcOpts,
|
|
65
|
-
|
|
66
|
-
log: message => {
|
|
67
|
-
/* c8 ignore next */
|
|
68
|
-
const logs = Array.isArray(message.logs) ? message.logs : [message.logs]
|
|
69
|
-
this._forwardLogs(logs)
|
|
70
|
-
},
|
|
71
|
-
...itcOpts.handlers
|
|
72
|
-
}
|
|
63
|
+
name: 'child-manager'
|
|
73
64
|
})
|
|
74
65
|
|
|
75
66
|
this.#id = generateChildrenId(context)
|
|
@@ -238,11 +229,6 @@ export class ChildManager extends ITC {
|
|
|
238
229
|
this.#server.close()
|
|
239
230
|
}
|
|
240
231
|
|
|
241
|
-
/* c8 ignore next 3 */
|
|
242
|
-
_forwardLogs (logs) {
|
|
243
|
-
workerData.loggingPort.postMessage({ logs: logs.map(m => JSON.stringify(m)) })
|
|
244
|
-
}
|
|
245
|
-
|
|
246
232
|
async #childProcessFetchHandler (req, res) {
|
|
247
233
|
const { url, headers } = req
|
|
248
234
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ITC } from '@platformatic/itc'
|
|
2
2
|
import { client, collectMetrics } from '@platformatic/metrics'
|
|
3
|
-
import {
|
|
3
|
+
import { disablePinoDirectWrite, ensureFlushedWorkerStdio, ensureLoggableError, features } from '@platformatic/utils'
|
|
4
4
|
import diagnosticChannel, { tracingChannel } from 'node:diagnostics_channel'
|
|
5
5
|
import { EventEmitter, once } from 'node:events'
|
|
6
6
|
import { readFile } from 'node:fs/promises'
|
|
@@ -194,6 +194,9 @@ export class ChildProcess extends ITC {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
#setupLogger () {
|
|
197
|
+
disablePinoDirectWrite()
|
|
198
|
+
ensureFlushedWorkerStdio()
|
|
199
|
+
|
|
197
200
|
// Since this is executed by user code, make sure we only override this in the main thread
|
|
198
201
|
// The rest will be intercepted by the BaseStackable.
|
|
199
202
|
const pinoOptions = {
|
|
@@ -209,18 +212,7 @@ export class ChildProcess extends ITC {
|
|
|
209
212
|
}
|
|
210
213
|
}
|
|
211
214
|
|
|
212
|
-
|
|
213
|
-
pinoOptions.transport = {
|
|
214
|
-
target: new URL('./child-transport.js', import.meta.url).toString()
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
this.#logger = pino(pinoOptions)
|
|
218
|
-
|
|
219
|
-
Reflect.defineProperty(process, 'stdout', { value: createPinoWritable(this.#logger, 'info', false, 'STDOUT') })
|
|
220
|
-
Reflect.defineProperty(process, 'stderr', { value: createPinoWritable(this.#logger, 'error', true, 'STDERR') })
|
|
221
|
-
} else {
|
|
222
|
-
this.#logger = pino(pinoOptions)
|
|
223
|
-
}
|
|
215
|
+
this.#logger = pino(pinoOptions)
|
|
224
216
|
}
|
|
225
217
|
|
|
226
218
|
#setupServer () {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/basic",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.38.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"split2": "^4.2.0",
|
|
25
25
|
"undici": "^7.0.0",
|
|
26
26
|
"ws": "^8.18.0",
|
|
27
|
-
"@platformatic/
|
|
28
|
-
"@platformatic/
|
|
29
|
-
"@platformatic/telemetry": "2.
|
|
30
|
-
"@platformatic/metrics": "2.
|
|
31
|
-
"@platformatic/utils": "2.
|
|
27
|
+
"@platformatic/itc": "2.38.0",
|
|
28
|
+
"@platformatic/config": "2.38.0",
|
|
29
|
+
"@platformatic/telemetry": "2.38.0",
|
|
30
|
+
"@platformatic/metrics": "2.38.0",
|
|
31
|
+
"@platformatic/utils": "2.38.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"borp": "^0.19.0",
|
package/schema.json
CHANGED