Je veux implémenter un "wrapper de processus" dans Go. Fondamentalement, il va lancer un processus (disons un serveur de nœuds) et le surveiller (capturer des signaux comme SIGKILL, SIGTERM ...)
Je pense que la façon de faire est de lancer le serveur de noeud dans une routine go en utilisant syscall.Exec
:
func launchCmd(path string, args []string) {
err := syscall.Exec(path, args, os.Environ())
if err != nil {
panic(err)
}
}
Ensuite, je voudrais attraper tous les signaux possibles générés par la commande exécutée par syscall
. Je suis assez nouveau pour Go, toute aide serait appréciée.
Il existe trois façons d'exécuter un programme dans Go:
syscall
package avec syscall.Exec , syscall.ForkExec , syscall.StartProcessos
package avec os.StartProcessos/exec
package avec exec.Commandsyscall.StartProcess est de bas niveau. Il renvoie un uintptr
comme un handle.
os.StartProcess
vous donne une belle os.Process
struct que vous pouvez appeler Signal activé. os/exec
vous donne io.ReaderWriter
à utiliser sur un tuyau. Les deux utilisent syscall
en interne.
La lecture des signaux envoyés depuis un processus autre que le vôtre semble un peu délicat. Si c'était possible, syscall
serait en mesure de le faire. Je ne vois rien d'évident dans les packages de niveau supérieur.
Pour recevoir un signal, vous pouvez utiliser signal.Notify comme ceci:
sigc := make(chan os.Signal, 1)
signal.Notify(sigc,
syscall.SIGHUP,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGQUIT)
go func() {
s := <-sigc
// ... do something ...
}()
Il vous suffit de changer les signaux que vous souhaitez écouter. Si vous ne spécifiez pas de signal, il captera tous les signaux pouvant être capturés.
Vous utiliseriez syscall.Kill ou Process.Signal pour mapper le signal. Vous pouvez obtenir le pid de Process.Pid
ou à la suite de syscall.StartProcess .
Vous pouvez utiliser signal.Notify :
import (
"os"
"os/signal"
"syscall"
)
func main() {
signalChannel := make(chan os.Signal, 2)
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
go func() {
sig := <-signalChannel
switch sig {
case os.Interrupt:
//handle SIGINT
case syscall.SIGTERM:
//handle SIGTERM
}
}()
// ...
}