mirror of
https://github.com/nonoo/kappanhang.git
synced 2026-01-04 15:59:58 +01:00
Auto restart executed commands
This commit is contained in:
parent
cf79868ae1
commit
38f73f6018
105
cmdrunner.go
Normal file
105
cmdrunner.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const startCmdDelay = time.Second
|
||||
|
||||
type cmdRunner struct {
|
||||
restartNeeded chan bool
|
||||
runEndNeeded chan bool
|
||||
runEndFinished chan bool
|
||||
}
|
||||
|
||||
var runCmdRunner cmdRunner
|
||||
var serialCmdRunner cmdRunner
|
||||
var rigctldRunner cmdRunner
|
||||
|
||||
func (c *cmdRunner) kill(cmd *exec.Cmd) {
|
||||
err := cmd.Process.Kill()
|
||||
if err != nil {
|
||||
err = cmd.Process.Signal(syscall.SIGKILL)
|
||||
if err != nil {
|
||||
log.Error("can't kill ", cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cmdRunner) run(cmdLine string) {
|
||||
var cmd *exec.Cmd
|
||||
|
||||
defer func() {
|
||||
if cmd != nil {
|
||||
c.kill(cmd)
|
||||
}
|
||||
c.runEndFinished <- true
|
||||
}()
|
||||
|
||||
s := strings.Split(cmdLine, " ")
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-c.runEndNeeded:
|
||||
return
|
||||
case <-time.After(startCmdDelay):
|
||||
}
|
||||
|
||||
cmd = exec.Command(s[0], s[1:]...)
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
log.Error("error starting ", cmd)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Print("started: ", cmd)
|
||||
|
||||
finishedChan := make(chan error)
|
||||
go func() {
|
||||
finishedChan <- cmd.Wait()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-c.restartNeeded:
|
||||
log.Debug("restarting ", cmd)
|
||||
c.kill(cmd)
|
||||
case err := <-finishedChan:
|
||||
if err != nil {
|
||||
log.Error(cmd, " error: ", err)
|
||||
}
|
||||
case <-c.runEndNeeded:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cmdRunner) startIfNeeded(cmdLine string) {
|
||||
if c.runEndNeeded != nil || cmdLine == "" || cmdLine == "-" {
|
||||
return
|
||||
}
|
||||
|
||||
c.restartNeeded = make(chan bool)
|
||||
c.runEndNeeded = make(chan bool)
|
||||
c.runEndFinished = make(chan bool)
|
||||
go c.run(cmdLine)
|
||||
}
|
||||
|
||||
func (c *cmdRunner) restart() {
|
||||
if c.restartNeeded == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.restartNeeded <- true
|
||||
}
|
||||
|
||||
func (c *cmdRunner) stop() {
|
||||
if c.runEndNeeded == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.runEndNeeded <- true
|
||||
<-c.runEndFinished
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -258,9 +259,13 @@ func (s *controlStream) handleRead(r []byte) error {
|
|||
s.serialAndAudioStreamOpened = true
|
||||
statusLog.startPeriodicPrint()
|
||||
|
||||
startCmdIfNeeded()
|
||||
startSerialPortCmdIfNeeded()
|
||||
startRigctldCmdIfNeeded()
|
||||
runCmdRunner.startIfNeeded(runCmd)
|
||||
if enableSerialDevice {
|
||||
serialCmdRunner.startIfNeeded(runCmdOnSerialPortCreated)
|
||||
}
|
||||
if !disableRigctld {
|
||||
rigctldRunner.startIfNeeded(fmt.Sprint("rigctld -m ", rigctldModel, " -r :", serialTCPPort))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
6
main.go
6
main.go
|
|
@ -132,9 +132,9 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
stopCmd()
|
||||
stopSerialPortCmd()
|
||||
stopRigctldCmd()
|
||||
runCmdRunner.stop()
|
||||
serialCmdRunner.stop()
|
||||
rigctldRunner.stop()
|
||||
audio.deinit()
|
||||
serialTCPSrv.deinit()
|
||||
serialPort.deinit()
|
||||
|
|
|
|||
123
runcmd.go
123
runcmd.go
|
|
@ -1,123 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const startCmdDelay = time.Second
|
||||
|
||||
var startedRigctldCmd *exec.Cmd
|
||||
var rigctldCmdStartTimer *time.Timer
|
||||
var startedCmd *exec.Cmd
|
||||
var cmdStartTimer *time.Timer
|
||||
var serialPortStartedCmd *exec.Cmd
|
||||
var serialPortCmdStartTimer *time.Timer
|
||||
|
||||
func doStartRigctldCmd() {
|
||||
startedRigctldCmd = exec.Command("rigctld", "-m", fmt.Sprint(rigctldModel), "-r",
|
||||
fmt.Sprint(":", serialTCPPort))
|
||||
err := startedRigctldCmd.Start()
|
||||
if err == nil {
|
||||
log.Print("rigctld started: ", startedRigctldCmd)
|
||||
} else {
|
||||
log.Error("error starting rigctld: ", err)
|
||||
startedCmd = nil
|
||||
}
|
||||
rigctldCmdStartTimer = nil
|
||||
}
|
||||
|
||||
func startRigctldCmdIfNeeded() {
|
||||
if startedRigctldCmd != nil || disableRigctld {
|
||||
return
|
||||
}
|
||||
|
||||
if rigctldCmdStartTimer != nil {
|
||||
rigctldCmdStartTimer.Stop()
|
||||
}
|
||||
rigctldCmdStartTimer = time.AfterFunc(startCmdDelay, doStartRigctldCmd)
|
||||
}
|
||||
|
||||
func stopRigctldCmd() {
|
||||
if startedRigctldCmd == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := startedRigctldCmd.Process.Kill(); err != nil {
|
||||
log.Error("failed to stop rigctld: ", err)
|
||||
}
|
||||
_ = startedRigctldCmd.Wait()
|
||||
startedRigctldCmd = nil
|
||||
}
|
||||
|
||||
func doStartCmd() {
|
||||
c := strings.Split(runCmd, " ")
|
||||
startedCmd = exec.Command(c[0], c[1:]...)
|
||||
err := startedCmd.Start()
|
||||
if err == nil {
|
||||
log.Print("cmd started: ", runCmd)
|
||||
} else {
|
||||
log.Error("error starting ", runCmd, ": ", err)
|
||||
startedCmd = nil
|
||||
}
|
||||
cmdStartTimer = nil
|
||||
}
|
||||
|
||||
func startCmdIfNeeded() {
|
||||
if startedCmd != nil || runCmd == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if cmdStartTimer != nil {
|
||||
cmdStartTimer.Stop()
|
||||
}
|
||||
cmdStartTimer = time.AfterFunc(startCmdDelay, doStartCmd)
|
||||
}
|
||||
|
||||
func stopCmd() {
|
||||
if startedCmd == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := startedCmd.Process.Kill(); err != nil {
|
||||
log.Error("failed to stop cmd ", runCmd, ": ", err)
|
||||
}
|
||||
startedCmd = nil
|
||||
}
|
||||
|
||||
func doSerialPortStartCmd() {
|
||||
c := strings.Split(runCmdOnSerialPortCreated, " ")
|
||||
serialPortStartedCmd = exec.Command(c[0], c[1:]...)
|
||||
err := serialPortStartedCmd.Start()
|
||||
if err == nil {
|
||||
log.Print("cmd started: ", runCmdOnSerialPortCreated)
|
||||
} else {
|
||||
log.Error("error starting ", runCmdOnSerialPortCreated, ": ", err)
|
||||
serialPortStartedCmd = nil
|
||||
}
|
||||
serialPortCmdStartTimer = nil
|
||||
}
|
||||
|
||||
func startSerialPortCmdIfNeeded() {
|
||||
if !enableSerialDevice || serialPortStartedCmd != nil || runCmdOnSerialPortCreated == "-" {
|
||||
return
|
||||
}
|
||||
|
||||
if serialPortCmdStartTimer != nil {
|
||||
serialPortCmdStartTimer.Stop()
|
||||
}
|
||||
serialPortCmdStartTimer = time.AfterFunc(startCmdDelay, doSerialPortStartCmd)
|
||||
}
|
||||
|
||||
func stopSerialPortCmd() {
|
||||
if serialPortStartedCmd == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := serialPortStartedCmd.Process.Kill(); err != nil {
|
||||
log.Error("failed to stop cmd ", runCmdOnSerialPortCreated, ": ", err)
|
||||
}
|
||||
serialPortStartedCmd = nil
|
||||
}
|
||||
|
|
@ -104,8 +104,7 @@ func (s *serialTCPSrvStruct) loop() {
|
|||
s.disconnectClient()
|
||||
log.Print("client ", s.client.RemoteAddr().String(), " disconnected")
|
||||
|
||||
stopRigctldCmd()
|
||||
startRigctldCmdIfNeeded()
|
||||
rigctldRunner.restart()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue