node build fixed
This commit is contained in:
96
seanime-2.9.10/internal/util/parallel/parallel.go
Normal file
96
seanime-2.9.10/internal/util/parallel/parallel.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package parallel
|
||||
|
||||
import (
|
||||
"github.com/samber/lo"
|
||||
"seanime/internal/util/limiter"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// EachTask iterates over elements of collection and invokes the task function for each element.
|
||||
// `task` is called in parallel.
|
||||
func EachTask[T any](collection []T, task func(item T, index int)) {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i, item := range collection {
|
||||
wg.Add(1)
|
||||
go func(_item T, _i int) {
|
||||
defer wg.Done()
|
||||
task(_item, _i)
|
||||
}(item, i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// EachTaskL is the same as EachTask, but takes a pointer to limiter.Limiter.
|
||||
func EachTaskL[T any](collection []T, rl *limiter.Limiter, task func(item T, index int)) {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i, item := range collection {
|
||||
wg.Add(1)
|
||||
go func(_item T, _i int) {
|
||||
defer wg.Done()
|
||||
rl.Wait()
|
||||
task(_item, _i)
|
||||
}(item, i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
type SettledResults[T comparable, R any] struct {
|
||||
Collection []T
|
||||
Fulfilled map[T]R
|
||||
Results []R
|
||||
Rejected map[T]error
|
||||
}
|
||||
|
||||
// NewSettledResults returns a pointer to a new SettledResults struct.
|
||||
func NewSettledResults[T comparable, R any](c []T) *SettledResults[T, R] {
|
||||
return &SettledResults[T, R]{
|
||||
Collection: c,
|
||||
Fulfilled: map[T]R{},
|
||||
Rejected: map[T]error{},
|
||||
}
|
||||
}
|
||||
|
||||
// GetFulfilledResults returns a pointer to the slice of fulfilled results and a boolean indicating whether the slice is not nil.
|
||||
func (sr *SettledResults[T, R]) GetFulfilledResults() (*[]R, bool) {
|
||||
if sr.Results != nil {
|
||||
return &sr.Results, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// AllSettled executes the provided task function once, in parallel for each element in the slice passed to NewSettledResults.
|
||||
// It returns a map of fulfilled results and a map of errors whose keys are the elements of the slice.
|
||||
func (sr *SettledResults[T, R]) AllSettled(task func(item T, index int) (R, error)) (map[T]R, map[T]error) {
|
||||
var wg sync.WaitGroup
|
||||
var mu sync.Mutex
|
||||
|
||||
for i, item := range sr.Collection {
|
||||
wg.Add(1)
|
||||
go func(_item T, _i int) {
|
||||
|
||||
res, err := task(_item, _i)
|
||||
|
||||
mu.Lock()
|
||||
if err != nil {
|
||||
sr.Rejected[_item] = err
|
||||
} else {
|
||||
sr.Fulfilled[_item] = res
|
||||
}
|
||||
mu.Unlock()
|
||||
wg.Done()
|
||||
|
||||
}(item, i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
sr.Results = lo.MapToSlice(sr.Fulfilled, func(key T, value R) R {
|
||||
return value
|
||||
})
|
||||
|
||||
return sr.Fulfilled, sr.Rejected
|
||||
}
|
||||
Reference in New Issue
Block a user