I am trying to create a Circuit breaker pattern, I want to execute a command exec.Command and if it fails, retry in X defined amount of time, for testing purposes, I am doing something like this for testing time.AfterFunc
:
package main
import (
"fmt"
"time"
)
func myFunc() error {
for i := 1; i < 10; i++ {
fmt.Printf("i = %+v\n", i)
if i%3 == 0 {
return fmt.Errorf("error")
}
}
return nil
}
func main() {
run := make(chan struct{}, 1)
run <- struct{}{}
for {
select {
case <-run:
err := myFunc()
if err != nil {
time.AfterFunc(3*time.Second, func() {
run <- struct{}{}
})
}
default:
}
}
}
time.AfterFunc
works for the above code, but not for the example below, I had to replace it with a sleep
in order to achieve the expected results:
package main
import (
"fmt"
"os/exec"
"time"
)
func Exec(done chan<- error) error {
cmd := exec.Command("./start")
if err := cmd.Start(); err != nil {
return err
}
go func() {
done <- cmd.Wait()
}()
return nil
}
func main() {
var (
run = make(chan struct{}, 1)
done = make(chan error, 1)
)
Exec(done)
for {
select {
case <-run:
err := Exec(done)
if err != nil {
fmt.Println(err)
// time.AfterFunc(3*time.Second, func() {
time.Sleep(3 * time.Second)
run <- struct{}{}
}
default:
select {
case err := <-done:
fmt.Println(err)
run <- struct{}{}
}
}
}
}
The content of ./sleep
:
#!/bin/sh
sleep 3
And for testing, creating an error, I toggle perms:
chmod -x sleep
chmod +x sleep
Therefore wondering what are the differences between using time.AfterFunc
and time.Sleep
and what could be the best way of implementing this pattern.
Aucun commentaire:
Enregistrer un commentaire