panic_group.go 540 B

123456789101112131415161718192021222324252627282930313233343536373839
  1. package main
  2. import "sync"
  3. type panicGroup struct {
  4. wg sync.WaitGroup
  5. errOnce sync.Once
  6. err error
  7. }
  8. func (g *panicGroup) Wait() error {
  9. g.wg.Wait()
  10. return g.err
  11. }
  12. func (g *panicGroup) Go(f func() error) {
  13. g.wg.Add(1)
  14. go func() {
  15. defer g.wg.Done()
  16. defer func() {
  17. if r := recover(); r != nil {
  18. if err, ok := r.(error); ok {
  19. g.errOnce.Do(func() {
  20. g.err = err
  21. })
  22. } else {
  23. panic(r)
  24. }
  25. }
  26. }()
  27. if err := f(); err != nil {
  28. g.errOnce.Do(func() {
  29. g.err = err
  30. })
  31. }
  32. }()
  33. }