execute: use goroutines + mutex to more efficiently serialize non-async cases

This commit is contained in:
Joel Elkins 2022-08-13 12:52:28 -05:00
parent 46ad4e6d87
commit 288dc71490
No known key found for this signature in database
GPG Key ID: 133589DC38921AE2

View File

@ -22,7 +22,9 @@ THE SOFTWARE.
package cmd
import (
"fmt"
"sync"
"time"
"gitea.elkins.co/Networking/ccl/internal/pkg/command"
"gitea.elkins.co/Networking/ccl/internal/pkg/container"
@ -31,12 +33,27 @@ import (
func execForEach(tgts []container.Container, getSet func(*container.Container) command.CommandSet) {
var wg sync.WaitGroup
var ser sync.Mutex // serialize non-async containers
for i := range tgts {
async := !tgts[i].StartOrder.Valid
runSet := func(cont *container.Container) {
async := tgts[i].StartOrder.ValueOrZero() == 0
wg.Add(1)
if async {
defer wg.Done()
// TODO: need to log errors on this branch
go runSet(&tgts[i], getSet, &wg)
} else {
ser.Lock()
go func(cont *container.Container, ser *sync.Mutex) {
defer ser.Unlock()
runSet(cont, getSet, &wg)
time.Sleep(5 * time.Second)
}(&tgts[i], &ser)
}
}
wg.Wait()
}
func runSet(cont *container.Container, getSet func(*container.Container) command.CommandSet, wg *sync.WaitGroup) {
defer wg.Done()
set := getSet(cont)
for _, cmd := range set.Commands {
if err := cmd.Execute(output, fake, set.ID); err != nil {
@ -48,13 +65,13 @@ func execForEach(tgts []container.Container, getSet func(*container.Container) c
}
}
}
if async {
wg.Add(1)
go runSet(&tgts[i])
} else {
runSet(&tgts[i])
// For debugging
func printConts(conts []container.Container) {
names := []string{}
for i := range conts {
names = append(names, fmt.Sprintf("[%s %d]", conts[i].Name, conts[i].StartOrder.ValueOrZero()))
}
}
wg.Wait()
fmt.Printf("%v\n", names)
}