Last active
April 23, 2023 00:23
-
-
Save neilotoole/1537017f110687d577033a9123145b9c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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