Bir spawn çocuk sürecini başladıktan sonra ayırın


9

Bir spawn çocuk sürecine şu şekilde başlarım:

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

process.unref()

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

Süreci başlattığımda çıktısını okumak istediğim için bağlı tutmam gerekiyor. Ancak Düğüm sürecimi (ebeveyn) kapatmadan hemen önce, arka planda çalışmasını sağlamak için bitmemiş tüm çocuk süreçlerini ayırmak istiyorum, ancak belgelerin söylediği gibi:

Uzun süren bir işlemi başlatmak için ayrılmış seçeneği kullanırken, üst öğeye bağlı olmayan bir stdio yapılandırması sağlanmadığı sürece, üst öğeden çıktıktan sonra işlem arka planda çalışmaya devam etmez.

Ama seçenek ile hangi bir sorun olduğunu stdio: 'ignore'okuyamıyorum stdout.

Ana işlemi kapatmak için önce boruları manuel olarak kapatmaya çalıştım ama başarısız oldu:

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

1
Düğümden bağımsız bir işlemin stdout / stderr'ını neden okuyabileceğinizi biraz kafam karıştı. Çıktıyı yakalamanız gerekir, çünkü işlem programınızın bir parçası olan görevleri (sadece paralel olarak çalışır) gerçekleştirir, bu durumda Düğüm üst olmalıdır ; veya gerçekten bağımsız bir program başlatıyorsanız, bu durumda standart çıktısı Düğüm programınızın endişesi değildir ve verileri iki bağımsız program (örn. veritabanı, dosya monitörü, API sunucusu) için anlamlı olacak şekilde paylaşmalısınız. , her neyse).
Mike 'Pomax' Kamermans

Belki yeterince açık değildim, sürece başladığımda onu bağlı tutmalıyım çünkü çıktısını okumak istiyorum. Ancak Düğüm sürecimi (ebeveyn) kapatmadan hemen önce, arka planda çalışmasını sağlamak için bitmemiş tüm çocuk süreçlerini ayırmak istiyorum.
Opsse

Neden farklı süreçlere / programlara sahip değilsiniz ve bir dosya veya başka bir yol kullanarak aralarında veri paylaşmıyorsunuz.
ROOT

Bir borunun yaptığı şey değil mi? Yani süreçler arasındaki iletişimi kendim halletmeyi mi öneriyorsun?
Opsse

Peki ama neden süreci kopardınız? Ya programınıza hizmet eden bir şey yapıyor, bu durumda programınız bitene kadar beklemeli, ya da zamanının bittiğini ve ne yapması gerektiğini bitirmesi gerektiği sürecini işaret etmeli çünkü SIGKILL'd - Temel olarak - : asıl kullanım durumu nedir? Çünkü bu, bir şey yapmaya çalıştığınız bir XY sorunu için birincil bir aday gibi görünüyor ve bunu yapmanın bir yolunu düşündünüz ve orijinal sorunu sormak yerine bir şeyler yapmayı düşünüyorsunuz
Mike 'Pomax' Kamermans

Yanıtlar:


1

Birçok testten sonra bu sorunu çözmenin en az bir yolunu buldum: ana işlemden ayrılmadan önce tüm boruları yok etmek.

Zor bir nokta, çocuk sürecinin boruları yok ederek doğru bir şekilde işlemesi gerektiğidir, eğer değilse bir hata alabilir ve yine de kapanabilir. Bu örnekte, düğüm alt işleminin bu konuda bir sorunu yoktur, ancak diğer senaryolarda farklı olabilir.

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)

çıktı

Start Main
Veri var: Start Child

Veri var: çocuktan merhaba Veri var: çocuktan merhaba Veri var: çocuktan
merhaba
Veri var: çocuktan
merhaba Çocuğun
bağlantısını kes

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.