Skip to content

Instantly share code, notes, and snippets.

@ivarprudnikov
Created November 5, 2021 18:07
Show Gist options
  • Save ivarprudnikov/827b09ff2057568a9448304ce897f8ed to your computer and use it in GitHub Desktop.
Save ivarprudnikov/827b09ff2057568a9448304ce897f8ed to your computer and use it in GitHub Desktop.
Go parallel execution
package main
import (
"errors"
"log"
"time"
"sync"
"fmt"
)
func ping(wg *sync.WaitGroup, fatalErrors chan error, url string) {
defer wg.Done()
fmt.Printf("ping %v: Started\n", url)
time.Sleep(time.Second)
if url == "err" {
fatalErrors <- errors.New(fmt.Sprintf("Error in host %s", url))
}
fmt.Printf("ping %v: Finished\n", url)
}
func main() {
start := time.Now()
urls := [4]string{"https://google.com", "https://cisco.com", "https://amazon.com", "err"}
// Make channels to pass fatal errors in WaitGroup
fatalErrors := make(chan error)
wgDone := make(chan bool)
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go ping(&wg, fatalErrors, url)
}
// Important final goroutine to wait until WaitGroup is done
go func() {
wg.Wait()
close(wgDone)
}()
// Wait until either WaitGroup is done or an error is received through the channel
select {
case <-wgDone:
break
case err := <-fatalErrors:
elapsed := time.Since(start)
close(fatalErrors)
log.Fatal(fmt.Sprintf("Error caught, time: %s", elapsed), err)
}
elapsed := time.Since(start)
log.Println(fmt.Sprintf("Success, time: %s", elapsed))
}
$ go run .
Worker https://cisco.com: Started
Worker https://amazon.com: Started
Worker https://google.com: Started
Worker err: Started
Worker err: Finished
Worker https://amazon.com: Finished
Worker https://google.com: Finished
Worker https://cisco.com: Finished
2021/11/05 18:05:02 Error caught, time: 1.000449656s Error in host err
exit status 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment