Skip to content

Instantly share code, notes, and snippets.

@justinschuldt
Created December 11, 2021 00:22
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 justinschuldt/047a8263f8b967e69f9915f13188ac9b to your computer and use it in GitHub Desktop.
Save justinschuldt/047a8263f8b967e69f9915f13188ac9b to your computer and use it in GitHub Desktop.
golang parallel async tasks, sending results to channel, completion tracked by WaitGroup
package main
import (
"fmt"
"sync"
"time"
)
type QueryResult struct {
key string
result string
}
func main() {
// runs tasks in parallel, tracking completion with a WaitGroup.
// tasks publish their result to a channel.
// channel is closed when WaitGroup finishes.
start := time.Now()
queries := map[string]int{
"a": 1,
"b": 3,
"c": 3,
"d": 3,
"e": 5,
}
numQueries := len(queries)
var wg sync.WaitGroup
wg.Add(numQueries)
resultChan := make(chan QueryResult)
for key, waitTime := range queries {
go func(k string, num int) {
defer wg.Done()
fmt.Printf("Going to query for key %s...\n", k)
// sleep to mock a long running task
time.Sleep(time.Duration(num) * time.Second)
res := QueryResult{key: k, result: "done"}
resultChan <- res
}(key, waitTime)
}
// async wait and close channel
go func() {
wg.Wait()
close(resultChan)
}()
results := map[string]string{}
for res := range resultChan {
fmt.Println("received result", res)
results[res.key] = res.result
}
fmt.Println("collected results:", results)
fmt.Println("took", time.Since(start))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment