forked from testcontainers/testcontainers-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move parallel implementation into single file
- Loading branch information
Vladimir Stepanov
committed
Jun 13, 2022
1 parent
e9cc2ac
commit a4edf72
Showing
3 changed files
with
111 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package testcontainers | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"sync" | ||
) | ||
|
||
const ( | ||
MaxGenericWorkers = 8 | ||
) | ||
|
||
type GenericParallelErrors struct { | ||
Errors []GenericContainerRequestError | ||
} | ||
|
||
func (gpe GenericParallelErrors) Error() string { | ||
return fmt.Sprintf("%v", gpe.Errors) | ||
} | ||
|
||
// GenericContainerRequestError represents error from parallel request | ||
type GenericContainerRequestError struct { | ||
Request GenericContainerRequest | ||
Error error | ||
} | ||
|
||
func genericContainerRunner( | ||
ctx context.Context, | ||
requests <-chan GenericContainerRequest, | ||
errors chan<- GenericContainerRequestError, | ||
containers chan<- Container, | ||
wg *sync.WaitGroup) { | ||
for req := range requests { | ||
c, err := GenericContainer(ctx, req) | ||
if err != nil { | ||
errors <- GenericContainerRequestError{ | ||
Request: req, | ||
Error: err, | ||
} | ||
continue | ||
} | ||
containers <- c | ||
} | ||
wg.Done() | ||
} | ||
|
||
// GenericParallelContainers creates a generic containers with parameters in parallel mode | ||
func GenericParallelContainers(ctx context.Context, reqs []GenericContainerRequest) ([]Container, error) { | ||
tasksChanSize := MaxGenericWorkers | ||
if tasksChanSize > len(reqs) { | ||
tasksChanSize = len(reqs) | ||
} | ||
|
||
tasksChan := make(chan GenericContainerRequest, tasksChanSize) | ||
errsChan := make(chan GenericContainerRequestError) | ||
resChan := make(chan Container) | ||
waitRes := make(chan struct{}) | ||
|
||
containers := make([]Container, 0) | ||
errors := make([]GenericContainerRequestError, 0) | ||
|
||
wg := sync.WaitGroup{} | ||
wg.Add(tasksChanSize) | ||
|
||
// run workers | ||
for i := 0; i < tasksChanSize; i++ { | ||
go genericContainerRunner(ctx, tasksChan, errsChan, resChan, &wg) | ||
} | ||
|
||
go func() { | ||
for { | ||
select { | ||
case c, ok := <-resChan: | ||
if !ok { | ||
resChan = nil | ||
} else { | ||
containers = append(containers, c) | ||
} | ||
case e, ok := <-errsChan: | ||
if !ok { | ||
errsChan = nil | ||
} else { | ||
errors = append(errors, e) | ||
} | ||
} | ||
|
||
if resChan == nil && errsChan == nil { | ||
waitRes <- struct{}{} | ||
break | ||
} | ||
} | ||
|
||
}() | ||
|
||
for _, req := range reqs { | ||
tasksChan <- req | ||
} | ||
close(tasksChan) | ||
wg.Wait() | ||
close(resChan) | ||
close(errsChan) | ||
|
||
<-waitRes | ||
|
||
if len(errors) == 0 { | ||
return containers, GenericParallelErrors{Errors: errors} | ||
} | ||
|
||
return containers, nil | ||
|
||
} |
File renamed without changes.