Skip to content

Instantly share code, notes, and snippets.

@cideM
Last active September 8, 2022 13:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cideM/3d7a0f88949ef64fb990f048dc0d280b to your computer and use it in GitHub Desktop.
Save cideM/3d7a0f88949ef64fb990f048dc0d280b to your computer and use it in GitHub Desktop.
Using semaphores
func main() {
source := []string{"FOO", "BAR", "BAX"}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
inputChannel, err := producer(ctx, source)
if err != nil {
log.Fatal(err)
}
outputChannel := make(chan string)
errorChannel := make(chan error)
limit := int64(runtime.NumCPU())
sem := semaphore.NewWeighted(limit)
go func() {
for {
select {
case <-ctx.Done():
break
case s, ok := <-inputChannel:
if ok {
if err := sem.Acquire(ctx, 1); err != nil {
log.Printf("Failed to acquire semaphore: %v", err)
break
}
go func(s string) {
defer sem.Release(1)
time.Sleep(time.Second * 3)
result := strings.ToLower(s)
outputChannel <- result
}(s)
} else {
if err := sem.Acquire(ctx, limit); err != nil {
log.Printf("Failed to acquire semaphore: %v", err)
}
close(outputChannel)
close(errorChannel)
}
}
}
}()
sink(ctx, cancel, outputChannel, errorChannel)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment