fix: will respwan when process is done.

Also added example and readme
This commit is contained in:
Eyal Shalev
2020-04-20 16:51:48 +03:00
parent 40f3c115f2
commit dac35eb34c
4 changed files with 200 additions and 6 deletions

107
README.md Normal file
View File

@@ -0,0 +1,107 @@
# go-supervisor (V2)
Small library for supervising child processes in `Go`, it exposes `Stdout`,`Stderr` and `Stdin` in the "Go way" using channels...
## Example
`echo.sh` print stuff to stdout and stderr and quit after 5 seconds...
```bash
#!/usr/bin/env bash
echo "STDOUT MESSAGE"
sleep 0.1
echo "STDERR MESSAGE" 1>&2
sleep 0.1
```
`supervisor-exapmle.go` spawn and supervise the bash program...
```go
package main
import (
"fmt"
"path/filepath"
"time"
"github.com/kontera-technologies/go-supervisor/v2"
)
func main() {
testDir, _ := filepath.Abs("testdata")
events := make(chan supervisor.Event)
p := supervisor.NewProcess(supervisor.ProcessOptions{
Name: "./example.sh",
Dir: testDir,
Id: "example",
EventNotifier: events,
OutputParser: supervisor.MakeBytesParser,
ErrorParser: supervisor.MakeBytesParser,
MaxSpawns: 4,
MaxSpawnAttempts: 2,
MaxInterruptAttempts: 3,
MaxTerminateAttempts: 5,
IdleTimeout: 10 * time.Second,
})
exit := make(chan bool)
go func() {
for {
select {
case msg := <-p.Stdout():
fmt.Printf("Recived STDOUT message: %s\n", *msg)
case msg := <-p.Stderr():
fmt.Printf("Recived STDERR message: %s\n", *msg)
case event := <-events:
switch event.Code {
case "ProcessStart":
fmt.Printf("Recived event: %s\n", event.Code)
default:
fmt.Printf("Recived event: %s - %s\n", event.Code, event.Message)
}
case <-p.DoneNotifier():
fmt.Println("Closing loop we are done...")
close(exit)
return
}
}
}()
if err := p.Start(); err != nil {
panic(fmt.Sprintf("failed to start process: %s", err))
}
<-exit
}
```
running the program should produce this output
```
Recived event: ProcessStart
Recived STDOUT message: STDOUT MESSAGE
Recived STDERR message: STDERR MESSAGE
Recived event: ProcessDone - exit status 0
Recived event: StoppingHeartbeatMonitoring - Stop signal received.
Recived event: Sleep - Sleeping for 1s before respwaning instance.
Recived event: ProcessRespawn - Trying to respawn instance.
Recived event: ProcessStart
Recived STDOUT message: STDOUT MESSAGE
Recived STDERR message: STDERR MESSAGE
Recived event: ProcessDone - exit status 0
Recived event: StoppingHeartbeatMonitoring - Stop signal received.
Recived event: Sleep - Sleeping for 1s before respwaning instance.
Recived event: ProcessRespawn - Trying to respawn instance.
Recived event: ProcessStart
Recived STDOUT message: STDOUT MESSAGE
Recived STDERR message: STDERR MESSAGE
Recived event: ProcessDone - exit status 0
Recived event: StoppingHeartbeatMonitoring - Stop signal received.
Recived event: Sleep - Sleeping for 1s before respwaning instance.
Recived event: ProcessRespawn - Trying to respawn instance.
Recived event: ProcessStart
Recived STDOUT message: STDOUT MESSAGE
Recived STDERR message: STDERR MESSAGE
Recived event: ProcessDone - exit status 0
Recived event: StoppingHeartbeatMonitoring - Stop signal received.
Recived event: RespawnError - Max number of respawns reached.
Closing loop we are done...
```

87
example_test.go Normal file
View File

@@ -0,0 +1,87 @@
package supervisor_test
import (
"fmt"
"path/filepath"
"time"
"github.com/kontera-technologies/go-supervisor/v2"
)
func Example() {
testDir, _ := filepath.Abs("testdata")
events := make(chan supervisor.Event)
p := supervisor.NewProcess(supervisor.ProcessOptions{
Name: "./example.sh",
Dir: testDir,
Id: "example",
EventNotifier: events,
OutputParser: supervisor.MakeBytesParser,
ErrorParser: supervisor.MakeBytesParser,
MaxSpawns: 4,
MaxSpawnAttempts: 2,
MaxInterruptAttempts: 3,
MaxTerminateAttempts: 5,
IdleTimeout: 10 * time.Second,
})
exit := make(chan bool)
go func() {
for {
select {
case msg := <-p.Stdout():
fmt.Printf("Recived STDOUT message: %s\n", *msg)
case msg := <-p.Stderr():
fmt.Printf("Recived STDERR message: %s\n", *msg)
case event := <-events:
switch event.Code {
case "ProcessStart":
fmt.Printf("Recived event: %s\n", event.Code)
default:
fmt.Printf("Recived event: %s - %s\n", event.Code, event.Message)
}
case <-p.DoneNotifier():
fmt.Println("Closing loop we are done...")
close(exit)
return
}
}
}()
if err := p.Start(); err != nil {
panic(fmt.Sprintf("failed to start process: %s", err))
}
<-exit
// Output:
// Recived event: ProcessStart
// Recived STDOUT message: STDOUT MESSAGE
// Recived STDERR message: STDERR MESSAGE
// Recived event: ProcessDone - exit status 0
// Recived event: StoppingHeartbeatMonitoring - Stop signal received.
// Recived event: Sleep - Sleeping for 1s before respwaning instance.
// Recived event: ProcessRespawn - Trying to respawn instance.
// Recived event: ProcessStart
// Recived STDOUT message: STDOUT MESSAGE
// Recived STDERR message: STDERR MESSAGE
// Recived event: ProcessDone - exit status 0
// Recived event: StoppingHeartbeatMonitoring - Stop signal received.
// Recived event: Sleep - Sleeping for 1s before respwaning instance.
// Recived event: ProcessRespawn - Trying to respawn instance.
// Recived event: ProcessStart
// Recived STDOUT message: STDOUT MESSAGE
// Recived STDERR message: STDERR MESSAGE
// Recived event: ProcessDone - exit status 0
// Recived event: StoppingHeartbeatMonitoring - Stop signal received.
// Recived event: Sleep - Sleeping for 1s before respwaning instance.
// Recived event: ProcessRespawn - Trying to respawn instance.
// Recived event: ProcessStart
// Recived STDOUT message: STDOUT MESSAGE
// Recived STDERR message: STDERR MESSAGE
// Recived event: ProcessDone - exit status 0
// Recived event: StoppingHeartbeatMonitoring - Stop signal received.
// Recived event: RespawnError - Max number of respawns reached.
// Closing loop we are done...
}

View File

@@ -374,12 +374,6 @@ func (p *Process) waitAndNotify() {
}
p.ensureAllClosed()
if state.Success() {
p.notifyEvent("ProcessStopped", "Process existed successfully.")
p.notifyDone()
return
}
if !p.canRespawn() {
p.notifyEvent("RespawnError", "Max number of respawns reached.")
p.notifyDone()

6
testdata/example.sh vendored Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
echo "STDOUT MESSAGE"
sleep 0.1
echo "STDERR MESSAGE" 1>&2
sleep 0.1