Skip to content

Commit

Permalink
Issue #111 - fix transitive dependency skip on failure
Browse files Browse the repository at this point in the history
  • Loading branch information
F1bonacc1 committed Dec 8, 2023
1 parent 50b4a72 commit 2b5c7e8
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 14 deletions.
22 changes: 22 additions & 0 deletions fixtures-code/process-compose-transitive-dep.yaml
Original file line number Diff line number Diff line change
@@ -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 changes: 42 additions & 0 deletions issues/issue_111/process-compose-probes.yaml
Original file line number Diff line number Diff line change
@@ -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 changes: 26 additions & 0 deletions issues/issue_111/process-compose.yaml
Original file line number Diff line number Diff line change
@@ -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

28 changes: 22 additions & 6 deletions src/app/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
type Process struct {
sync.Mutex
globalEnv []string
confMtx sync.Mutex
procConf *types.ProcessConfig
procState *types.ProcessState
stateMtx sync.Mutex
Expand Down Expand Up @@ -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() {
Expand All @@ -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 {
Expand Down Expand Up @@ -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 == "" {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
}
19 changes: 11 additions & 8 deletions src/app/project_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
Expand Down
26 changes: 26 additions & 0 deletions src/app/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
})
}
1 change: 1 addition & 0 deletions src/types/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const (
ProcessStateRestarting = "Restarting"
ProcessStateTerminating = "Terminating"
ProcessStateCompleted = "Completed"
ProcessStateSkipped = "Skipped"
ProcessStateError = "Error"
)

Expand Down

0 comments on commit 2b5c7e8

Please sign in to comment.