public
Last active

This example shows how to have a set of goroutines running concurrently and processing requests. Panics from goroutines are recovered and the worker is restarted. You can download it and run it directly using `go run letitfail.go`

  • Download Gist
letitfail.go
Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
package main
 
import (
"bufio"
"fmt"
"os"
"time"
)
 
const numWorkers = 3
 
var (
workers chan bool
requests chan string
)
 
// worker executes requests.
func worker(id int) {
for {
switch r := <-requests; r {
case "sleep":
fmt.Println(id, "sleeping")
time.Sleep(5 * time.Second)
case "echo":
fmt.Println(id, "echo")
case "quit":
os.Exit(0)
default:
panic(fmt.Sprintf("%v unkown command %q", id, r))
}
}
}
 
// run runs a function and catches any panic.
func run(f func(int), id int) {
defer func() {
if rec := recover(); rec != nil {
fmt.Println("restarting failed worker: ", rec)
}
workers <- true
}()
f(id)
}
 
// monitor ensures that as numWorkers goroutines are running
// at any time.
func monitor() {
workers = make(chan bool, numWorkers)
for i := 0; i < cap(workers); i++ {
workers <- true
}
 
id := 0
for _ = range workers {
id++
go run(worker, id)
}
}
 
// reader reads lines from stdin and puts them in the requests channel.
func reader() {
requests = make(chan string)
 
s := bufio.NewScanner(os.Stdin)
for s.Scan() {
requests <- s.Text()
}
}
 
func main() {
go monitor()
reader()
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.