package main
import (
"context"
"fmt"
"golang.org/x/sync/errgroup"
"sync"
"time"
)
func workerPool(ctx context.Context, numWorkers, numTasks int) ([]string, error) {
taskChan := make(chan int, numTasks)
resultChan := make(chan string, numTasks)
// Create worker pool
g, ctx := errgroup.WithContext(ctx)
g.SetLimit(numWorkers)
// Start workers
for i := 0; i < numWorkers; i++ {
g.Go(func() error {
for {
select {
case <-ctx.Done():
return ctx.Err()
case taskID, ok := <-taskChan:
if !ok {
return nil
}
// Process task
time.Sleep(time.Millisecond * time.Duration(100+taskID*10))
resultChan <- fmt.Sprintf("Processed task %d", taskID)
}
}
})
}
// Feed tasks
go func() {
for i := 1; i <= numTasks; i++ {
taskChan <- i
}
close(taskChan)
}()
// Collect results
var results []string
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for result := range resultChan {
results = append(results, result)
}
}()
// Wait for completion
if err := g.Wait(); err != nil {
return nil, err
}
close(resultChan)
wg.Wait()
return results, nil
}
func main() {
ctx := context.Background()
results, err := workerPool(ctx, 10, 50)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Summary: Completed %d tasks\n", len(results))
}
No comments:
Post a Comment