Separar un proceso secundario de generación después del inicio

9

Comienzo un proceso de generación de hijos de esta manera:

let process = spawn(apiPath, {
  detached: true
})

process.unref()

process.stdout.on('data', data => { /* do something */ })

Cuando comienzo el proceso, necesito mantenerlo adjunto porque quiero leer su salida. Pero justo antes de cerrar mi proceso de Nodo (el padre), quiero separar todos los procesos secundarios no terminados para mantenerlos ejecutándose en segundo plano, pero como dice la documentación :

Cuando se utiliza la opción separada para iniciar un proceso de larga duración, el proceso no se mantendrá ejecutándose en segundo plano después de que el padre salga a menos que cuente con una configuración estándar que no esté conectada al padre.

Pero con la opción stdio: 'ignore'no puedo leer lo stdoutque es un problema.

Traté de cerrar las tuberías manualmente antes de cerrar el proceso padre, pero no tuvo éxito:

// Trigger just before the main process end
process.stdin.end()
process.stderr.unpipe()
process.stdout.unpipe()
Opsse
fuente
1
Estoy un poco confundido por qué esperarías poder leer stdout / stderr de un proceso que es independiente de Node. O necesita capturar la salida, porque el proceso está realizando tareas que son parte de su programa (solo se ejecuta en paralelo), en cuyo caso Node debería ser el padre; o está comenzando un programa verdaderamente independiente, en cuyo caso su salida estándar no es asunto de su programa Node y debe hacer que compartan datos de una manera que tenga sentido para dos programas independientes (por ejemplo, una base de datos, un monitor de archivos, un servidor API , lo que sea).
Mike 'Pomax' Kamermans
Tal vez no estaba lo suficientemente claro, cuando comienzo el proceso necesito mantenerlo adjunto porque quiero leer su salida. Pero justo antes de cerrar mi proceso de Nodo (el padre) quiero separar todos los procesos secundarios no terminados para mantenerlos en ejecución en segundo plano.
Opsse
¿Por qué no tener diferentes procesos / programas y compartir datos entre ellos utilizando un archivo o algún otro medio?
RAÍZ
¿No es lo que hace una pipa? ¿Entonces sugieres manejar la comunicación entre procesos yo mismo?
Opsse
Pero, ¿por qué separarías el proceso? O está haciendo algo al servicio de su programa, en cuyo caso su programa debería esperar hasta que termine, o debería indicarle al proceso que está fuera de tiempo y necesita terminar lo que está haciendo porque está a punto de SIGKILL'd - Básicamente : ¿Cuál es el caso de uso real? Porque esto suena como un candidato principal para un problema XY en el que estás tratando de hacer algo, y pensaste en una forma de hacerlo, y preguntas sobre esa forma de hacer las cosas en lugar de preguntar sobre el problema original
Mike 'Pomax' Kamermans

Respuestas:

1

Después de muchas pruebas, encontré al menos una forma de resolver este problema: destruir todas las tuberías antes de abandonar el proceso principal.

Un punto complicado es que el proceso secundario tiene que manejar correctamente la destrucción de las tuberías, de lo contrario, podría tener un error y cerrarse de todos modos. En este ejemplo, el proceso secundario del nodo parece no tener ningún problema con esto, pero podría ser diferente con otro escenario.

main.js

const { spawn } = require('child_process')

console.log('Start Main')

let child = spawn('node', ['child.js'], { detached: true })
child.unref() // With this the main process end after fully disconnect the child

child.stdout.on('data', data => {
  console.log(`Got data : ${data}`)
})

// In real case should be triggered just before the end of the main process
setTimeout(() => {
  console.log('Disconnect the child')

  child.stderr.unpipe()
  child.stderr.destroy()
  child.stdout.unpipe()
  child.stdout.destroy()
  child.stdin.end()
  child.stdin.destroy()
}, 5000)

child.js

console.log('Start Child')

setInterval(function() {
   process.stdout.write('hello from child')
}, 1000)

salida

Inicio Principal
Datos obtenidos: Iniciar hijo

Datos obtenidos: hola del niño
Datos obtenidos: hola del niño
Datos obtenidos: hola del niño
Datos obtenidos: hola del niño
Desconecte al niño

Opsse
fuente