Go has no built-in supervisor tree; you must implement one using goroutines, channels, and context to manage child lifecycles. Create a parent goroutine that spawns children, monitors their exit channels, and restarts them if they crash.
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context, id int, done chan<- int) {
for {
select {
case <-ctx.Done():
return
default:
fmt.Printf("Worker %d running\n", id)
time.Sleep(2 * time.Second)
}
}
}
func supervisor(ctx context.Context, id int, restarts chan<- int) {
for {
childDone := make(chan int, 1)
childCtx, cancel := context.WithCancel(ctx)
go worker(childCtx, id, childDone)
<-childDone
cancel()
restarts <- id
if ctx.Err() != nil {
return
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
restarts := make(chan int, 10)
go supervisor(ctx, 1, restarts)
time.Sleep(10 * time.Second)
for i := 0; i < 5; i++ {
fmt.Println("Restarted:", <-restarts)
}
}