Skip to content

Instantly share code, notes, and snippets.

@neilotoole
Last active April 23, 2023 00:23
Show Gist options
  • Save neilotoole/1537017f110687d577033a9123145b9c to your computer and use it in GitHub Desktop.
Save neilotoole/1537017f110687d577033a9123145b9c to your computer and use it in GitHub Desktop.
package main
import (
"context"
"errors"
"fmt"
"github.com/sergerad/miscgo/pkg/relax"
"golang.org/x/sync/errgroup"
)
func main() {
//main1()
main2()
}
func main2() {
g, ctx := errgroup.WithContext(context.Background())
fmt.Println("Hello World")
defer fmt.Println("Goodbye World")
// Do work, one will fail, all will finish
g.Go(safeCall(func() error {
return gone(ctx, "go1", false)
}))
g.Go(safeCall(func() error {
return gone(ctx, "go2", false)
}))
g.Go(safeCall(func() error {
return gone(ctx, "go3", true)
}))
// Wait for all
if err := g.Wait(); err != nil {
fmt.Println("failed successfully")
}
}
func safeCall(fn func() error) func() error {
return func() error {
var err error
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered from panic:", r)
err = errors.New(fmt.Sprintf("recovered from panic: %v", r))
}
}()
err = fn()
return err
}
}
func gone(ctx context.Context, id string, fail bool) error {
if fail {
fmt.Printf("panicking: %s\n", id)
panic("bad")
}
select {
case <-ctx.Done():
if ctx.Err() != nil {
// ...
}
default:
}
fmt.Printf("shutting down: %s\n", id)
return nil
}
func main1() {
// Set up root context and error group
g, ctx := relax.Main()
fmt.Println("Hello World")
defer fmt.Println("Goodbye World")
// Do work, one will fail, all will finish
g.Go(func() error {
defer relax.Routine(ctx)
return gone(ctx, "go1", false)
})
g.Go(func() error {
defer relax.Routine(ctx)
return gone(ctx, "go2", false)
})
g.Go(func() error {
defer relax.Routine(ctx)
return gone(ctx, "go3", true)
})
// Wait for all
if err := g.Wait(); err != nil {
fmt.Println("failed successfully")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment