54 lines
1.2 KiB
Go
54 lines
1.2 KiB
Go
|
package types
|
||
|
|
||
|
import (
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
type syncGroupFunc func()
|
||
|
|
||
|
// SyncGroup is essentially a wrapper around sync.WaitGroup, designed for ease of use. You only need to use Add() to
|
||
|
// add routines and Run() to execute them. When it's time to close or reset, you just need to call WaitAndClear(),
|
||
|
// which takes care of waiting for all the routines to complete before clearing routine.
|
||
|
//
|
||
|
// It eliminates the need for manual management of sync.WaitGroup. Specifically, it highlights that SyncGroup takes
|
||
|
// care of sync.WaitGroup.Add() and sync.WaitGroup.Done() automatically, reducing the chances of missing these crucial calls.
|
||
|
type SyncGroup struct {
|
||
|
wg sync.WaitGroup
|
||
|
|
||
|
sgFuncsMu sync.Mutex
|
||
|
sgFuncs []syncGroupFunc
|
||
|
}
|
||
|
|
||
|
func NewSyncGroup() SyncGroup {
|
||
|
return SyncGroup{}
|
||
|
}
|
||
|
|
||
|
func (w *SyncGroup) WaitAndClear() {
|
||
|
w.wg.Wait()
|
||
|
|
||
|
w.sgFuncsMu.Lock()
|
||
|
w.sgFuncs = []syncGroupFunc{}
|
||
|
w.sgFuncsMu.Unlock()
|
||
|
}
|
||
|
|
||
|
func (w *SyncGroup) Add(fn syncGroupFunc) {
|
||
|
w.wg.Add(1)
|
||
|
|
||
|
w.sgFuncsMu.Lock()
|
||
|
w.sgFuncs = append(w.sgFuncs, fn)
|
||
|
w.sgFuncsMu.Unlock()
|
||
|
}
|
||
|
|
||
|
func (w *SyncGroup) Run() {
|
||
|
w.sgFuncsMu.Lock()
|
||
|
fns := w.sgFuncs
|
||
|
w.sgFuncsMu.Unlock()
|
||
|
|
||
|
for _, fn := range fns {
|
||
|
go func(doFunc syncGroupFunc) {
|
||
|
defer w.wg.Done()
|
||
|
doFunc()
|
||
|
}(fn)
|
||
|
}
|
||
|
}
|