func gracefulRestart(rcvr *receiver.Receiver, serviceMgr *serviceManager, cfgPath, join string) { if !filepath.IsAbs(os.Args[0]) { log.Printf("ERROR: Graceful restart only possible when %q started with absolute path, ignoring this request.", os.Args[0]) return } files, protos := serviceMgr.listenerFilesAndProtocols() log.Printf("gracefulRestart(): Beginning graceful restart with sockets: %v and protos: %q", files, protos) rcvr.ClusterReady(false) // triggers a transition // Allow enough time for a transition to start time.Sleep(500 * time.Millisecond) // TODO This is a hack mypath, _ := filepath.Abs(os.Args[0]) // TODO we should really be the starting working directory args := []string{ "-c", cfgPath, "-graceful", protos} if join != "" { args = append(args, "-join", join) } cmd := exec.Command(mypath, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.ExtraFiles = files // The new process will kill -TERM us when it's ready err := cmd.Start() if err != nil { log.Printf("gracefulRestart(): Failed to launch, error: %v", err) } else { gracefulChildPid = cmd.Process.Pid log.Printf("gracefulRestart(): Forked child, waiting to be killed...") } }
func gracefulExit(rcvr *receiver.Receiver, serviceMgr *serviceManager) { log.Printf("Gracefully exiting...") quitting = true if gracefulChildPid == 0 { rcvr.ClusterReady(false) // triggers a transition // Allow enough time for a transition to start time.Sleep(500 * time.Millisecond) // TODO This is a hack } log.Printf("Waiting for all TCP connections to finish...") serviceMgr.closeListeners() log.Printf("TCP connections finished.") // Stop the receiver rcvr.Stop() if gracefulChildPid != 0 { // let the child know the data is flushed syscall.Kill(gracefulChildPid, syscall.SIGUSR1) } }