package main

import (
	"fmt"
	"time"

	"github.com/sourcegraph/conc"
)

// section: note
/*
This example demonstrates the waitgroup.Go() pattern as implemented by the
production-ready github.com/sourcegraph/conc library.

conc.WaitGroup automatically captures panics in child goroutines and surfaces
them when you call Wait() or WaitAndRecover().
*/
// section: note

// section: main
func main() {
	fmt.Println("=== conc.WaitGroup Example ===\n")

	var wg conc.WaitGroup

	for i := 0; i < 3; i++ {
		i := i // capture range variable
		wg.Go(func() {
			fmt.Printf("worker %d starting\n", i)
			time.Sleep(time.Duration(i+1) * 50 * time.Millisecond)
			fmt.Printf("worker %d done\n", i)
		})
	}

	// conc.WaitGroup captures panics and returns them via WaitAndRecover.
	wg.Go(func() {
		fmt.Println("failing worker starting")
		time.Sleep(30 * time.Millisecond)
		panic("worker panic")
	})

	if rec := wg.WaitAndRecover(); rec != nil {
		fmt.Printf("recovered panic: %v\n", rec.Value)
	}

	fmt.Println("all tasks accounted for")
}

// section: main

// section: output
/*
Sample output (order may vary with scheduler):
=== conc.WaitGroup Example ===

failing worker starting
worker 1 starting
worker 2 starting
worker 0 starting
worker 0 done
worker 1 done
worker 2 done
recovered panic: worker panic
all tasks accounted for
*/
// section: output
