add NoRestartOn config parameter
This commit is contained in:
parent
20cb7b9255
commit
2c5c669c72
@ -19,6 +19,8 @@ processes:
|
|||||||
env:
|
env:
|
||||||
TARGET: example.com
|
TARGET: example.com
|
||||||
|
|
||||||
|
dir: "/tmp"
|
||||||
|
|
||||||
# pmux uses an exponential backoff when restarting a process, so subsequent
|
# pmux uses an exponential backoff when restarting a process, so subsequent
|
||||||
# restarts will each take longer and longer. minWait/maxWait indicate the
|
# restarts will each take longer and longer. minWait/maxWait indicate the
|
||||||
# min/max wait times between restarts of this process, respectively.
|
# min/max wait times between restarts of this process, respectively.
|
||||||
|
@ -27,7 +27,7 @@ type Config struct {
|
|||||||
|
|
||||||
// Dir is the directory the process will be run in. If not set then the
|
// Dir is the directory the process will be run in. If not set then the
|
||||||
// process is run in the same directory as this parent process.
|
// process is run in the same directory as this parent process.
|
||||||
Dir string
|
Dir string `yaml:"dir"`
|
||||||
|
|
||||||
// MinWait and MaxWait are the minimum and maximum amount of time between
|
// MinWait and MaxWait are the minimum and maximum amount of time between
|
||||||
// restarts that RunProcess will wait.
|
// restarts that RunProcess will wait.
|
||||||
@ -42,6 +42,10 @@ type Config struct {
|
|||||||
//
|
//
|
||||||
// Defalts to 10 seconds.
|
// Defalts to 10 seconds.
|
||||||
SigKillWait time.Duration `yaml:"sigKillWait"`
|
SigKillWait time.Duration `yaml:"sigKillWait"`
|
||||||
|
|
||||||
|
// NoRestartOn indicates which exit codes should result in the process not
|
||||||
|
// being restarted any further.
|
||||||
|
NoRestartOn []int `yaml:"no_restart_on"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg Config) withDefaults() Config {
|
func (cfg Config) withDefaults() Config {
|
||||||
@ -63,14 +67,15 @@ func (cfg Config) withDefaults() Config {
|
|||||||
|
|
||||||
// RunProcessOnce runs the process described by the Config (though it doesn't
|
// RunProcessOnce runs the process described by the Config (though it doesn't
|
||||||
// use all fields from the Config). The process is killed if the context is
|
// use all fields from the Config). The process is killed if the context is
|
||||||
// canceled.
|
// canceled. The exit status of the process is returned, or -1 if the process
|
||||||
|
// was never started.
|
||||||
//
|
//
|
||||||
// It returns nil if the process exits normally with a zero status. It returns
|
// It returns nil if the process exits normally with a zero status. It returns
|
||||||
// an error otherwise.
|
// an error otherwise.
|
||||||
//
|
//
|
||||||
// The stdout and stderr of the process will be written to the given Logger, as
|
// The stdout and stderr of the process will be written to the given Logger, as
|
||||||
// well as various runtime events.
|
// well as various runtime events.
|
||||||
func RunProcessOnce(ctx context.Context, logger Logger, cfg Config) error {
|
func RunProcessOnce(ctx context.Context, logger Logger, cfg Config) (int, error) {
|
||||||
|
|
||||||
cfg = cfg.withDefaults()
|
cfg = cfg.withDefaults()
|
||||||
|
|
||||||
@ -106,13 +111,13 @@ func RunProcessOnce(ctx context.Context, logger Logger, cfg Config) error {
|
|||||||
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting stdout pipe: %w", err)
|
return -1, fmt.Errorf("getting stdout pipe: %w", err)
|
||||||
}
|
}
|
||||||
defer stdout.Close()
|
defer stdout.Close()
|
||||||
|
|
||||||
stderr, err := cmd.StderrPipe()
|
stderr, err := cmd.StderrPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting stderr pipe: %w", err)
|
return -1, fmt.Errorf("getting stderr pipe: %w", err)
|
||||||
}
|
}
|
||||||
defer stderr.Close()
|
defer stderr.Close()
|
||||||
|
|
||||||
@ -120,7 +125,7 @@ func RunProcessOnce(ctx context.Context, logger Logger, cfg Config) error {
|
|||||||
fwdOutPipe(stderr)
|
fwdOutPipe(stderr)
|
||||||
|
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return fmt.Errorf("starting process: %w", err)
|
return -1, fmt.Errorf("starting process: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// go-routine which will sent interrupt if the context is cancelled. Also
|
// go-routine which will sent interrupt if the context is cancelled. Also
|
||||||
@ -148,11 +153,14 @@ func RunProcessOnce(ctx context.Context, logger Logger, cfg Config) error {
|
|||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if err := cmd.Wait(); err != nil {
|
err = cmd.Wait()
|
||||||
return fmt.Errorf("process exited: %w", err)
|
exitCode := cmd.ProcessState.ExitCode()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return exitCode, fmt.Errorf("process exited: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return exitCode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunProcess is a process (configured by Config) until the context is canceled,
|
// RunProcess is a process (configured by Config) until the context is canceled,
|
||||||
@ -172,19 +180,25 @@ func RunProcess(ctx context.Context, logger Logger, cfg Config) {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
err := RunProcessOnce(ctx, logger, cfg)
|
exitCode, err := RunProcessOnce(ctx, logger, cfg)
|
||||||
took := time.Since(start)
|
took := time.Since(start)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("%v", err)
|
logger.Printf("exit code %d, %v", exitCode, err)
|
||||||
} else {
|
} else {
|
||||||
logger.Println("exit status 0")
|
logger.Println("exit code 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := range cfg.NoRestartOn {
|
||||||
|
if cfg.NoRestartOn[i] == exitCode {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wait = ((wait * 2) - took).Truncate(time.Millisecond)
|
wait = ((wait * 2) - took).Truncate(time.Millisecond)
|
||||||
|
|
||||||
if wait < cfg.MinWait {
|
if wait < cfg.MinWait {
|
||||||
|
Loading…
Reference in New Issue
Block a user