Skip to content

Commit faf86f3

Browse files
committed
fix: deadlock when nesting serial/parallel exec
fixes a cache read deadlock when there is a serial or parallel exec includes in another serial or parallel exec
1 parent 441c06b commit faf86f3

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

internal/runner/parallel/parallel.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,18 @@ func (r *parallelRunner) Exec(
5151
if err != nil {
5252
return err
5353
}
54-
defer str.Close()
5554
if err := str.CreateBucket(store.EnvironmentBucket()); err != nil {
5655
return err
5756
}
58-
return handleExec(ctx, e, eng, parallelSpec, inputEnv, str)
57+
cacheData, err := str.GetAll()
58+
if err != nil {
59+
return err
60+
}
61+
if err := str.Close(); err != nil {
62+
ctx.Logger.Error(err, "unable to close store")
63+
}
64+
65+
return handleExec(ctx, e, eng, parallelSpec, inputEnv, cacheData)
5966
}
6067

6168
return fmt.Errorf("no parallel executables to run")
@@ -65,8 +72,9 @@ func (r *parallelRunner) Exec(
6572
func handleExec(
6673
ctx *context.Context, parent *executable.Executable,
6774
eng engine.Engine,
68-
parallelSpec *executable.ParallelExecutableType, promptedEnv map[string]string,
69-
str store.Store,
75+
parallelSpec *executable.ParallelExecutableType,
76+
promptedEnv map[string]string,
77+
cacheData map[string]string,
7078
) error {
7179
groupCtx, cancel := stdCtx.WithCancel(ctx.Ctx)
7280
defer cancel()
@@ -77,11 +85,7 @@ func handleExec(
7785
}
7886
group.SetLimit(limit)
7987

80-
dm, err := str.GetAll()
81-
if err != nil {
82-
return err
83-
}
84-
dataMap := expr.ExpressionEnv(ctx, parent, dm, promptedEnv)
88+
dataMap := expr.ExpressionEnv(ctx, parent, cacheData, promptedEnv)
8589

8690
var execs []engine.Exec
8791
for i, refConfig := range parallelSpec.Execs {

internal/runner/serial/serial.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,32 @@ func (r *serialRunner) Exec(
5151
if err != nil {
5252
return err
5353
}
54-
defer str.Close()
5554
if err := str.CreateBucket(store.EnvironmentBucket()); err != nil {
5655
return err
5756
}
58-
return handleExec(ctx, e, eng, serialSpec, inputEnv, str)
57+
cacheData, err := str.GetAll()
58+
if err != nil {
59+
return err
60+
}
61+
if err := str.Close(); err != nil {
62+
ctx.Logger.Error(err, "unable to close store")
63+
}
64+
65+
return handleExec(ctx, e, eng, serialSpec, inputEnv, cacheData)
5966
}
6067
return fmt.Errorf("no serial executables to run")
6168
}
6269

63-
//nolint:funlen,gocognit
70+
//nolint:gocognit
6471
func handleExec(
6572
ctx *context.Context,
6673
parent *executable.Executable,
6774
eng engine.Engine,
6875
serialSpec *executable.SerialExecutableType,
6976
promptedEnv map[string]string,
70-
str store.Store,
77+
cacheData map[string]string,
7178
) error {
72-
dm, err := str.GetAll()
73-
if err != nil {
74-
return err
75-
}
76-
dataMap := expr.ExpressionEnv(ctx, parent, dm, promptedEnv)
79+
dataMap := expr.ExpressionEnv(ctx, parent, cacheData, promptedEnv)
7780

7881
var execs []engine.Exec
7982
for i, refConfig := range serialSpec.Execs {

0 commit comments

Comments
 (0)