Created
July 30, 2022 07:23
-
-
Save flymop/388cf5548f0ec82fe0644c8a2042fbb4 to your computer and use it in GitHub Desktop.
An example on multi producer (sender) and single consumer (receiver) golang channel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://go.dev/play/p/z7lFk4D-mhA | |
package main | |
import ( | |
"context" | |
"fmt" | |
"math/rand" | |
"strconv" | |
"strings" | |
"sync" | |
"time" | |
) | |
func longRunningTask(idx int) string { | |
time.Sleep(time.Duration(rand.Intn(4)) * time.Second) | |
return "task completed: " + strconv.Itoa(idx) | |
} | |
func main() { | |
resultC := make(chan string, 20) | |
var wg sync.WaitGroup | |
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) | |
defer cancel() | |
rand.Seed(time.Now().UnixNano()) | |
// run tasks | |
for i := 0; i < 20; i++ { | |
wg.Add(1) | |
go func(ctx context.Context, i int) { | |
defer wg.Done() | |
result := longRunningTask(i) | |
// ramdomly pick a case when timeout | |
select { | |
case <-ctx.Done(): | |
return | |
default: | |
resultC <- result | |
} | |
}(ctx, i) | |
} | |
wg.Wait() | |
results := make([]string, 0) | |
runLoop: | |
for { | |
// safely drain the channel | |
if len(resultC) == 0 { | |
break runLoop | |
} | |
select { | |
case r := <-resultC: | |
results = append(results, r) | |
default: | |
} | |
} | |
// results handling, for example, print them | |
fmt.Printf("running task results:\n%s", strings.Join(results, ", ")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment