mirror of
https://github.com/F1bonacc1/process-compose.git
synced 2024-10-05 23:27:19 +03:00
Issue #111 - fix transitive dependency skip on failure
This commit is contained in:
parent
50b4a72d14
commit
2b5c7e8233
22
fixtures-code/process-compose-transitive-dep.yaml
Normal file
22
fixtures-code/process-compose-transitive-dep.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
version: "0.5"
|
||||
|
||||
log_level: debug
|
||||
log_length: 1000
|
||||
|
||||
processes:
|
||||
procA:
|
||||
command: "exit 1"
|
||||
|
||||
procB:
|
||||
command: echo "I shouldn't run"
|
||||
depends_on:
|
||||
procA:
|
||||
condition: process_completed_successfully
|
||||
|
||||
procC:
|
||||
command: echo "I shouldn't run"
|
||||
depends_on:
|
||||
procB:
|
||||
condition: process_completed_successfully
|
||||
|
||||
|
42
issues/issue_111/process-compose-probes.yaml
Normal file
42
issues/issue_111/process-compose-probes.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
version: "0.5"
|
||||
|
||||
log_level: debug
|
||||
log_length: 1000
|
||||
|
||||
processes:
|
||||
procA:
|
||||
command: "exit 1"
|
||||
readiness_probe:
|
||||
exec:
|
||||
command: "pidof process-compose"
|
||||
initial_delay_seconds: 1
|
||||
period_seconds: 1
|
||||
timeout_seconds: 1
|
||||
success_threshold: 1
|
||||
failure_threshold: 20
|
||||
|
||||
procB:
|
||||
command: echo "I shouldn't run"
|
||||
readiness_probe:
|
||||
exec:
|
||||
command: "pidof process-compose"
|
||||
initial_delay_seconds: 1
|
||||
period_seconds: 1
|
||||
timeout_seconds: 1
|
||||
success_threshold: 1
|
||||
failure_threshold: 20
|
||||
depends_on:
|
||||
procA:
|
||||
condition: process_healthy
|
||||
|
||||
procC:
|
||||
command: echo "I shouldn't run"
|
||||
depends_on:
|
||||
procB:
|
||||
condition: process_healthy
|
||||
|
||||
pc_log:
|
||||
command: "tail -f -n100 process-compose-${USER}.log"
|
||||
working_dir: "/tmp"
|
||||
namespace: debug
|
||||
|
26
issues/issue_111/process-compose.yaml
Normal file
26
issues/issue_111/process-compose.yaml
Normal file
@ -0,0 +1,26 @@
|
||||
version: "0.5"
|
||||
|
||||
log_level: debug
|
||||
log_length: 1000
|
||||
|
||||
processes:
|
||||
procA:
|
||||
command: "exit 1"
|
||||
|
||||
procB:
|
||||
command: echo "I shouldn't run"
|
||||
depends_on:
|
||||
procA:
|
||||
condition: process_completed_successfully
|
||||
|
||||
procC:
|
||||
command: echo "I shouldn't run"
|
||||
depends_on:
|
||||
procB:
|
||||
condition: process_completed_successfully
|
||||
|
||||
pc_log:
|
||||
command: "tail -f -n100 process-compose-${USER}.log"
|
||||
working_dir: "/tmp"
|
||||
namespace: debug
|
||||
|
@ -33,6 +33,7 @@ const (
|
||||
type Process struct {
|
||||
sync.Mutex
|
||||
globalEnv []string
|
||||
confMtx sync.Mutex
|
||||
procConf *types.ProcessConfig
|
||||
procState *types.ProcessState
|
||||
stateMtx sync.Mutex
|
||||
@ -134,11 +135,11 @@ func (p *Process) run() int {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
_ = p.command.Wait()
|
||||
p.Lock()
|
||||
p.procState.ExitCode = p.command.ExitCode()
|
||||
p.setExitCode(p.command.ExitCode())
|
||||
p.Unlock()
|
||||
log.Info().
|
||||
Str("process", p.getName()).
|
||||
Int("exit_code", p.procState.ExitCode).
|
||||
Int("exit_code", p.getExitCode()).
|
||||
Msg("Exited")
|
||||
|
||||
if p.isDaemonLaunched() {
|
||||
@ -164,7 +165,7 @@ func (p *Process) run() int {
|
||||
}
|
||||
}
|
||||
p.onProcessEnd(types.ProcessStateCompleted)
|
||||
return p.procState.ExitCode
|
||||
return p.getExitCode()
|
||||
}
|
||||
|
||||
func (p *Process) getProcessStarter() func() error {
|
||||
@ -227,7 +228,7 @@ func (p *Process) getProcessEnvironment() []string {
|
||||
|
||||
func (p *Process) isRestartable() bool {
|
||||
p.Lock()
|
||||
exitCode := p.procState.ExitCode
|
||||
exitCode := p.getExitCode()
|
||||
p.Unlock()
|
||||
if p.procConf.RestartPolicy.Restart == types.RestartPolicyNo ||
|
||||
p.procConf.RestartPolicy.Restart == "" {
|
||||
@ -263,7 +264,7 @@ func (p *Process) waitForCompletion() int {
|
||||
for !p.done {
|
||||
p.procCond.Wait()
|
||||
}
|
||||
return p.procState.ExitCode
|
||||
return p.getExitCode()
|
||||
}
|
||||
|
||||
func (p *Process) waitUntilReady() bool {
|
||||
@ -274,13 +275,14 @@ func (p *Process) waitUntilReady() bool {
|
||||
return true
|
||||
}
|
||||
log.Error().Msgf("Process %s was aborted and won't become ready", p.getName())
|
||||
p.setExitCode(1)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Process) wontRun() {
|
||||
p.onProcessEnd(types.ProcessStateCompleted)
|
||||
p.onProcessEnd(types.ProcessStateSkipped)
|
||||
}
|
||||
|
||||
// perform graceful process shutdown if defined in configuration
|
||||
@ -506,6 +508,8 @@ func (p *Process) setStateAndRun(state string, runnable func() error) error {
|
||||
|
||||
func (p *Process) onStateChange(state string) {
|
||||
switch state {
|
||||
case types.ProcessStateSkipped:
|
||||
p.setExitCode(1)
|
||||
case types.ProcessStateRestarting:
|
||||
fallthrough
|
||||
case types.ProcessStateLaunching:
|
||||
@ -621,3 +625,15 @@ func (p *Process) getOpenPorts(ports *types.ProcessPorts) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Process) getExitCode() int {
|
||||
defer p.confMtx.Unlock()
|
||||
p.confMtx.Lock()
|
||||
return p.procState.ExitCode
|
||||
}
|
||||
|
||||
func (p *Process) setExitCode(code int) {
|
||||
defer p.confMtx.Unlock()
|
||||
p.confMtx.Lock()
|
||||
p.procState.ExitCode = code
|
||||
}
|
||||
|
@ -109,18 +109,18 @@ func (p *ProjectRunner) runProcess(config *types.ProcessConfig) {
|
||||
)
|
||||
p.addRunningProcess(process)
|
||||
p.waitGroup.Add(1)
|
||||
go func() {
|
||||
defer p.removeRunningProcess(process)
|
||||
go func(proc *Process) {
|
||||
defer p.removeRunningProcess(proc)
|
||||
defer p.waitGroup.Done()
|
||||
if err = p.waitIfNeeded(process.procConf); err != nil {
|
||||
if err = p.waitIfNeeded(proc.procConf); err != nil {
|
||||
log.Error().Msgf("Error: %s", err.Error())
|
||||
log.Error().Msgf("Error: process %s won't run", process.getName())
|
||||
process.wontRun()
|
||||
log.Error().Msgf("Error: process %s won't run", proc.getName())
|
||||
proc.wontRun()
|
||||
} else {
|
||||
exitCode := process.run()
|
||||
p.onProcessEnd(exitCode, process.procConf)
|
||||
exitCode := proc.run()
|
||||
p.onProcessEnd(exitCode, proc.procConf)
|
||||
}
|
||||
}()
|
||||
}(process)
|
||||
}
|
||||
|
||||
func (p *ProjectRunner) waitIfNeeded(process *types.ProcessConfig) error {
|
||||
@ -145,7 +145,10 @@ func (p *ProjectRunner) waitIfNeeded(process *types.ProcessConfig) error {
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
log.Error().Msgf("Error: process %s depends on %s, but it isn't running", process.ReplicaName, k)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -281,3 +281,29 @@ func TestSystem_TestComposeScale(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSystem_TestTransitiveDependency(t *testing.T) {
|
||||
fixture1 := filepath.Join("..", "..", "fixtures-code", "process-compose-transitive-dep.yaml")
|
||||
t.Run(fixture1, func(t *testing.T) {
|
||||
project, err := loader.Load(&loader.LoaderOptions{
|
||||
FileNames: []string{fixture1},
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
runner, err := NewProjectRunner(&ProjectOpts{
|
||||
project: project,
|
||||
processesToRun: []string{},
|
||||
mainProcessArgs: []string{},
|
||||
})
|
||||
runner.Run()
|
||||
|
||||
states, err := runner.GetProcessesState()
|
||||
for _, state := range states.States {
|
||||
if state.ExitCode != 1 {
|
||||
t.Errorf("process %s exit code is not 1", state.Name)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -123,6 +123,7 @@ const (
|
||||
ProcessStateRestarting = "Restarting"
|
||||
ProcessStateTerminating = "Terminating"
|
||||
ProcessStateCompleted = "Completed"
|
||||
ProcessStateSkipped = "Skipped"
|
||||
ProcessStateError = "Error"
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user