Skip to content

Commit

Permalink
Cancel other executing targets when one fails.
Browse files Browse the repository at this point in the history
  • Loading branch information
ejholmes committed Jan 15, 2017
1 parent b119233 commit f91f82b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 3 deletions.
10 changes: 9 additions & 1 deletion plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,18 @@ func (p *Plan) newTarget(ctx context.Context, target string) (Target, error) {
// Rule. Targets Exec functions are gauranteed to be called when all of the
// Targets dependencies have been fulfilled.
func (p *Plan) Exec(ctx context.Context, semaphore Semaphore) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()

return p.graph.Walk(func(t Target) error {
semaphore.P()
defer semaphore.V()
return t.Exec(ctx)
err := t.Exec(ctx)
if err != nil {
// Cancel all other currently executing targets.
cancel()
}
return err
})
}

Expand Down
12 changes: 11 additions & 1 deletion plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,20 @@ func TestPlan_Cancel(t *testing.T) {
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()
err := Exec(ctx, NewSemaphore(0), "test/000-cancel/all").(*dag.MultiError)
assert.Equal(t, 1, len(err.Errors))
assert.Equal(t, 2, len(err.Errors))
assert.True(t, strings.Contains(err.Errors[0].Error(), "signal: killed"))
}

func TestPlan_Cancel_Fail(t *testing.T) {
clean(t)

err := Exec(ctx, NewSemaphore(0), "test/000-cancel/all", "test/000-cancel/fail").(*dag.MultiError)
assert.Equal(t, 3, len(err.Errors))
assert.True(t, strings.Contains(err.Errors[0].Error(), "exit status 1"))
assert.True(t, strings.Contains(err.Errors[1].Error(), "signal: killed"))
assert.True(t, strings.Contains(err.Errors[2].Error(), "signal: killed"))
}

func TestTarget_Dependencies(t *testing.T) {
wd, err := os.Getwd()
assert.NoError(t, err)
Expand Down
7 changes: 6 additions & 1 deletion test/000-cancel/all.walk
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/bin/bash

deps() {
echo a.sleep
echo b.sleep
}

case $1 in
exec) exec sleep 60 ;;
deps) deps ;;
esac
5 changes: 5 additions & 0 deletions test/000-cancel/default.sleep.walk
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

case $1 in
exec) echo "Sleeping..." && exec sleep 60 ;;
esac
5 changes: 5 additions & 0 deletions test/000-cancel/fail.walk
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

case $1 in
exec) exit 1 ;;
esac

0 comments on commit f91f82b

Please sign in to comment.