Wednesday, January 14, 2026

goroutine 4 - ErrGroup with Context and Worker Pool

 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