Skip to content
This repository was archived by the owner on Jul 18, 2024. It is now read-only.

Commit 62b5b65

Browse files
authored
Merge pull request #9 from ash2k/ash2k/fix-regression
Signal processes to stop on error and don't start new ones
2 parents 92145d6 + eabb80f commit 62b5b65

File tree

8 files changed

+67
-32
lines changed

8 files changed

+67
-32
lines changed

multirun/multirun.go

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"io"
7+
"sync"
78
)
89

910
type multirun struct {
@@ -29,6 +30,8 @@ func (m multirun) run(ctx context.Context) error {
2930

3031
// unboundedExecution execute multiple commands without concurrency limit
3132
func (m multirun) unboundedExecution(ctx context.Context) error {
33+
ctx, cancel := context.WithCancel(ctx)
34+
defer cancel()
3235
errs := make(chan error)
3336

3437
for _, cmd := range m.commands {
@@ -48,7 +51,9 @@ func (m multirun) unboundedExecution(ctx context.Context) error {
4851

4952
var firstError error
5053
for range m.commands {
51-
if err := <-errs; firstError == nil {
54+
err := <-errs
55+
if err != nil && firstError == nil {
56+
cancel()
5257
firstError = err
5358
}
5459
}
@@ -58,34 +63,50 @@ func (m multirun) unboundedExecution(ctx context.Context) error {
5863

5964
// boundedExecution execute multiple commands using a sized worker pool
6065
func (m multirun) boundedExecution(ctx context.Context) error {
66+
ctx, cancel := context.WithCancel(ctx)
67+
defer cancel()
6168
// errs should be buffered to avoid blocking
6269
// when len(m.commands) > m.jobs
6370
errs := make(chan error, len(m.commands))
64-
commands := make(chan command)
65-
66-
// start worker pool
67-
for w := 0; w < m.jobs; w++ {
68-
go m.spawnWorker(ctx, commands, errs)
69-
}
71+
commands := make(chan command, len(m.commands))
7072

7173
// send command to worker pool
7274
for _, cmd := range m.commands {
7375
commands <- cmd
7476
}
7577
close(commands)
7678

77-
var firstError error
78-
for range m.commands {
79-
if err := <-errs; firstError == nil {
80-
firstError = err
81-
}
79+
// start worker pool
80+
var wg sync.WaitGroup
81+
wg.Add(m.jobs)
82+
for w := 0; w < m.jobs; w++ {
83+
go func() {
84+
defer wg.Done()
85+
err := m.spawnWorker(ctx, commands)
86+
if err != nil {
87+
errs <- err // first error must go first, cancel after it has been sent.
88+
cancel()
89+
}
90+
}()
8291
}
8392

84-
return firstError
93+
wg.Wait()
94+
close(errs)
95+
96+
for err := range errs {
97+
return err
98+
}
99+
100+
return nil
85101
}
86102

87-
func (m multirun) spawnWorker(ctx context.Context, commands <-chan command, errs chan<- error) {
103+
func (m multirun) spawnWorker(ctx context.Context, commands <-chan command) error {
88104
for cmd := range commands {
105+
select {
106+
case <-ctx.Done():
107+
return ctx.Err()
108+
default:
109+
}
89110
p := process{
90111
tag: cmd.Tag,
91112
path: cmd.Path,
@@ -103,6 +124,10 @@ func (m multirun) spawnWorker(ctx context.Context, commands <-chan command, errs
103124
fmt.Fprintf(m.stderrSink, "Running %s\n", cmd.Tag)
104125
}
105126

106-
errs <- p.run(ctx)
127+
err := p.run(ctx)
128+
if err != nil {
129+
return err
130+
}
107131
}
132+
return nil
108133
}

multirun/test/BUILD.bazel

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ multirun(
130130
":command_echo_2",
131131
":command_echo_1",
132132
],
133-
parallel = True,
133+
jobs = 0,
134134
)
135135

136136
multirun(
137137
name = "multirun_parallel_tagged_success",
138-
parallel = True,
138+
jobs = 0,
139139
tagged_commands = {
140140
":command_echo_2": "echo-2",
141141
":command_echo_1": "echo-1",
@@ -182,10 +182,10 @@ multirun(
182182
name = "multirun_parallel_failure",
183183
commands = [
184184
":command_echo_2",
185-
":command_exit",
186-
":command_echo_3",
185+
":command_sleep_and_exit_0",
186+
":command_sleep_and_exit_5",
187187
],
188-
parallel = True,
188+
jobs = 0,
189189
)
190190

191191
command(
@@ -269,22 +269,30 @@ sh_binary(
269269
multirun(
270270
name = "multirun_signal_handling",
271271
commands = [
272-
":command_sleep_and_exit",
272+
":command_sleep_and_exit_0",
273273
],
274274
)
275275

276276
multirun(
277277
name = "multirun_parallel_signal_handling",
278278
commands = [
279-
":command_sleep_and_exit",
279+
":command_sleep_and_exit_0",
280+
],
281+
jobs = 0,
282+
)
283+
284+
command(
285+
name = "command_sleep_and_exit_0",
286+
arguments = [
287+
"4", "0",
280288
],
281-
parallel = True,
289+
command = ":sleep_and_exit",
282290
)
283291

284292
command(
285-
name = "command_sleep_and_exit",
293+
name = "command_sleep_and_exit_5",
286294
arguments = [
287-
"4",
295+
"1", "5",
288296
],
289297
command = ":sleep_and_exit",
290298
)
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[//multirun/test:command_echo_2] command_2 a
22
[//multirun/test:command_echo_2] command_2 b
33
[//multirun/test:command_echo_2] command_2 c
4-
[//multirun/test:command_echo_3] command_3 a
5-
[//multirun/test:command_exit] exiting 5
4+
[//multirun/test:command_sleep_and_exit_0] sleeping before exiting 4
5+
[//multirun/test:command_sleep_and_exit_5] exiting: 5
6+
[//multirun/test:command_sleep_and_exit_5] sleeping before exiting 1
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
RAK>>running multirun/test/multirun_parallel_signal_handling.bash
22
RAK>>sleeping 2
3-
[//multirun/test:command_sleep_and_exit] sleeping before exiting 4
3+
[//multirun/test:command_sleep_and_exit_0] sleeping before exiting 4
44
RAK>>killing with signal SIGINT
55
RAK>>done
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
RAK>>running multirun/test/multirun_parallel_signal_handling.bash
22
RAK>>sleeping 2
3-
[//multirun/test:command_sleep_and_exit] sleeping before exiting 4
3+
[//multirun/test:command_sleep_and_exit_0] sleeping before exiting 4
44
RAK>>killing with signal SIGTERM
55
RAK>>done

multirun/test/expected_sigint.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
RAK>>running multirun/test/multirun_signal_handling.bash
22
RAK>>sleeping 2
3-
Running //multirun/test:command_sleep_and_exit
3+
Running //multirun/test:command_sleep_and_exit_0
44
sleeping before exiting 4
55
RAK>>killing with signal SIGINT
66
RAK>>done

multirun/test/expected_sigterm.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
RAK>>running multirun/test/multirun_signal_handling.bash
22
RAK>>sleeping 2
3-
Running //multirun/test:command_sleep_and_exit
3+
Running //multirun/test:command_sleep_and_exit_0
44
sleeping before exiting 4
55
RAK>>killing with signal SIGTERM
66
RAK>>done

multirun/test/sleep_and_exit.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
echo "sleeping before exiting $1"
44
sleep "$1"
5-
echo "exiting"
5+
echo "exiting: $2"
6+
exit "$2"

0 commit comments

Comments
 (0)