Stacca un processo figlio spawn dopo l'avvio


9

Inizi un processo figlio spawn in questo modo:

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

process.unref()

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

Quando inizio il processo devo tenerlo allegato perché voglio leggere il suo output. Ma appena prima di chiudere il mio processo Node (il genitore) voglio staccare tutti i processi figlio non finiti per mantenerli in esecuzione in background, ma come dice la documentazione :

Quando si utilizza l'opzione staccata per avviare un processo a esecuzione prolungata, il processo non rimarrà in esecuzione in background dopo la chiusura del genitore a meno che non sia fornito con una configurazione stdio che non è connessa al genitore.

Ma con l'opzione stdio: 'ignore'non riesco a leggere stdoutquale sia un problema.

Ho provato a chiudere manualmente i tubi prima di chiudere il processo principale ma non è riuscito:

// Trigger just before the main process end
process.stdin.end()
process.stderr.unpipe()
process.stdout.unpipe()

1
Sono un po 'confuso sul perché ti aspetteresti di poter leggere stdout / stderr di un processo che è indipendente da Node. O è necessario acquisire l'output, poiché il processo sta eseguendo attività che fanno parte del programma (solo in esecuzione in parallelo), nel qual caso Node dovrebbe essere il genitore; o stai avviando un programma veramente indipendente, nel qual caso il suo output standard non è una preoccupazione del tuo programma Node e dovresti farli condividere i dati in un modo che abbia senso per due programmi indipendenti (ad esempio un database, un monitor di file, un server API , qualunque cosa).
Mike 'Pomax' Kamermans,

Forse non ero abbastanza chiaro, quando avvio il processo devo tenerlo allegato perché voglio leggere il suo output. Ma appena prima di chiudere il mio processo Node (il genitore) voglio staccare tutti i processi figlio non finiti per mantenerli in esecuzione in background.
Opsse il

Perché non avere processi / programmi diversi e condividere i dati tra loro usando un file o altri mezzi.
ROOT

Non è quello che fa una pipa? Quindi suggerisci di gestire da solo la comunicazione tra i processi?
Opsse

Ma perché dovresti staccare il processo? O sta facendo qualcosa al servizio del tuo programma, nel qual caso il tuo programma dovrebbe aspettare fino a quando non è finito, oppure dovrebbe segnalare al processo che è fuori tempo e deve finire quello che sta facendo perché sta per ottenere SIGKILL'd - Fondamentalmente : qual è il caso d'uso reale? Perché questo suona come un candidato principale per un problema XY in cui stai cercando di fare qualcosa, e hai pensato a un modo per farlo, e stai chiedendo di quel modo di fare le cose invece di chiedere il problema originale
Mike 'Pomax' Kamermans il

Risposte:


1

Dopo molti test ho trovato almeno un modo per risolvere questo problema: distruggere tutti i tubi prima di abbandonare il processo principale.

Un punto complicato è che il processo figlio deve gestire correttamente la distruzione dei tubi, altrimenti potrebbe avere un errore e chiudere comunque. In questo esempio il processo figlio nodo sembra non avere problemi con questo, ma potrebbe essere diverso con altri scenari.

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)

produzione

Inizia principale
Dati ottenuti: avvia figlio

Dati ottenuti: ciao da bambino
Dati ottenuti: ciao da bambino
Dati ottenuti: ciao da bambino
Dati ottenuti: ciao da bambino
Disconnetti il ​​bambino

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.