node build fixed

This commit is contained in:
ra_ma
2025-09-20 14:08:38 +01:00
parent c6ebbe069d
commit 3d298fa434
1516 changed files with 535727 additions and 2 deletions

View 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
}

View File

@@ -0,0 +1,78 @@
package parallel
import (
"fmt"
"github.com/sourcegraph/conc/pool"
"github.com/sourcegraph/conc/stream"
"testing"
"time"
)
func fakeAPICall(id int) (int, error) {
//time.Sleep(time.Millisecond * time.Duration(100+rand.Intn(500)))
time.Sleep(time.Millisecond * 200)
return id, nil
}
func TestAllSettled(t *testing.T) {
ids := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
sr := NewSettledResults[int, int](ids)
sr.AllSettled(func(item int, index int) (int, error) {
return fakeAPICall(item)
})
fulfilled, ok := sr.GetFulfilledResults()
if !ok {
t.Error("expected results, got error")
}
for _, v := range *fulfilled {
t.Log(v)
}
}
func TestConc(t *testing.T) {
ids := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
fetch := func(ids []int) ([]int, error) {
p := pool.NewWithResults[int]().WithErrors()
for _, id := range ids {
id := id
p.Go(func() (int, error) {
return fakeAPICall(id)
})
}
return p.Wait()
}
res, _ := fetch(ids)
for _, v := range res {
t.Log(v)
}
}
func TestConcStream(t *testing.T) {
ids := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
strm := stream.New()
for _, id := range ids {
id := id
strm.Go(func() stream.Callback {
res, err := fakeAPICall(id)
// This will print in the order the tasks were submitted
return func() {
fmt.Println(res, err)
}
})
}
strm.Wait()
}