Skip to content

Instantly share code, notes, and snippets.

@ryanc414
Created June 6, 2021 20:34
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 ryanc414/a625b9b92e600df547d41bb9203d4860 to your computer and use it in GitHub Desktop.
Save ryanc414/a625b9b92e600df547d41bb9203d4860 to your computer and use it in GitHub Desktop.
Run pattern with error handling in Go
func run(ctx context.Context) error {
var h Handler
ctx, cancel := context.WithCancel(ctx)
eg, ctx := errgroup.WithContext(ctx)
eg.Go(func() error { return h.Run(ctx) })
eg.Go(func() error {
for i := 0; i < 10; i++ {
select {
case <-time.After(time.Second):
log.Print(h.GetVal())
case <-ctx.Done():
return ctx.Err()
}
}
cancel()
return nil
})
err := eg.Wait()
if errors.Is(err, context.Canceled) {
return nil
}
return err
}
type Handler struct {
val int
mu sync.Mutex
}
const (
LIMIT = 100
BOMB = 42
)
func (h *Handler) Run(ctx context.Context) error {
log.Print("Starting handler")
for {
select {
case <-time.After(100 * time.Millisecond):
val := rand.Intn(LIMIT)
if val == BOMB {
log.Print("returning BOMB from handler")
return errors.New("BOMB!")
}
h.mu.Lock()
h.val = val
h.mu.Unlock()
case <-ctx.Done():
log.Print("exiting handler")
return ctx.Err()
}
}
}
func (h *Handler) GetVal() int {
h.mu.Lock()
defer h.mu.Unlock()
return h.val
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment