@@ -2,7 +2,6 @@ package testcontainers
22
33import (
44 "context"
5- "errors"
65 "fmt"
76 "sync"
87)
@@ -32,24 +31,27 @@ func (gpe ParallelContainersError) Error() string {
3231 return fmt .Sprintf ("%v" , gpe .Errors )
3332}
3433
34+ // parallelContainersResult represents result.
35+ type parallelContainersResult struct {
36+ ParallelContainersRequestError
37+ Container Container
38+ }
39+
3540func parallelContainersRunner (
3641 ctx context.Context ,
3742 requests <- chan GenericContainerRequest ,
38- errorsCh chan <- ParallelContainersRequestError ,
39- containers chan <- Container ,
43+ results chan <- parallelContainersResult ,
4044 wg * sync.WaitGroup ,
4145) {
4246 defer wg .Done ()
4347 for req := range requests {
4448 c , err := GenericContainer (ctx , req )
49+ res := parallelContainersResult {Container : c }
4550 if err != nil {
46- errorsCh <- ParallelContainersRequestError {
47- Request : req ,
48- Error : errors .Join (err , TerminateContainer (c )),
49- }
50- continue
51+ res .Request = req
52+ res .Error = err
5153 }
52- containers <- c
54+ results <- res
5355 }
5456}
5557
@@ -65,41 +67,26 @@ func ParallelContainers(ctx context.Context, reqs ParallelContainerRequest, opt
6567 }
6668
6769 tasksChan := make (chan GenericContainerRequest , tasksChanSize )
68- errsChan := make (chan ParallelContainersRequestError )
69- resChan := make (chan Container )
70- waitRes := make (chan struct {})
71-
72- containers := make ([]Container , 0 )
73- errors := make ([]ParallelContainersRequestError , 0 )
70+ resultsChan := make (chan parallelContainersResult , tasksChanSize )
71+ done := make (chan struct {})
7472
75- wg := sync.WaitGroup {}
73+ var wg sync.WaitGroup
7674 wg .Add (tasksChanSize )
7775
7876 // run workers
7977 for i := 0 ; i < tasksChanSize ; i ++ {
80- go parallelContainersRunner (ctx , tasksChan , errsChan , resChan , & wg )
78+ go parallelContainersRunner (ctx , tasksChan , resultsChan , & wg )
8179 }
8280
81+ var errs []ParallelContainersRequestError
82+ containers := make ([]Container , 0 , len (reqs ))
8383 go func () {
84- for {
85- select {
86- case c , ok := <- resChan :
87- if ! ok {
88- resChan = nil
89- } else {
90- containers = append (containers , c )
91- }
92- case e , ok := <- errsChan :
93- if ! ok {
94- errsChan = nil
95- } else {
96- errors = append (errors , e )
97- }
98- }
99-
100- if resChan == nil && errsChan == nil {
101- waitRes <- struct {}{}
102- break
84+ defer close (done )
85+ for res := range resultsChan {
86+ if res .Error != nil {
87+ errs = append (errs , res .ParallelContainersRequestError )
88+ } else {
89+ containers = append (containers , res .Container )
10390 }
10491 }
10592 }()
@@ -108,14 +95,15 @@ func ParallelContainers(ctx context.Context, reqs ParallelContainerRequest, opt
10895 tasksChan <- req
10996 }
11097 close (tasksChan )
98+
11199 wg .Wait ()
112- close (resChan )
113- close (errsChan )
114100
115- <- waitRes
101+ close (resultsChan )
102+
103+ <- done
116104
117- if len (errors ) != 0 {
118- return containers , ParallelContainersError {Errors : errors }
105+ if len (errs ) != 0 {
106+ return containers , ParallelContainersError {Errors : errs }
119107 }
120108
121109 return containers , nil
0 commit comments