func (s *Supervisor) Add(service Service, opts ...ServiceOption) {
	s.addService(service, opts...)
}
Add inserts into the Supervisor tree a new permanent service. If the
Supervisor is already started, it will start it automatically.
package supervisor
import (
	"context"
	"fmt"
	"log"
	"sync"
	"time"
)
type processFailure func()
const AlwaysRestart = -1
type serviceType int
const (
	permanent serviceType = iota
	transient
	temporary
)
type ServiceSpecification struct {
	svc     Service
	svctype serviceType
}
type ServiceOption func(*ServiceSpecification)
func Permanent(s *ServiceSpecification) {
	s.svctype = permanent
}
func Transient(s *ServiceSpecification) {
	s.svctype = transient
}
func Temporary(s *ServiceSpecification) {
	s.svctype = temporary
}
type Service interface {
	Serve(ctx context.Context)
}
type Supervisor struct {
	Name string
	name string
	MaxRestarts int
	maxrestarts int
	MaxTime time.Duration
	maxtime time.Duration
	Log func(interface{})
	log func(interface{})
	prepared sync.Once
	added chan struct{}
	running         sync.Mutex
	runningServices sync.WaitGroup
	mu           sync.Mutex
	svcorder     []string                         
	services     map[string]ServiceSpecification  
	cancelations map[string]context.CancelFunc    
	terminations map[string]context.CancelFunc    
	lastRestart  time.Time
	restarts     int
}
func (s *Supervisor) prepare() {
	s.prepared.Do(s.reset)
}
func (s *Supervisor) reset() {
	s.mu.Lock()
	if s.Name == "" {
		s.Name = "supervisor"
	}
	if s.MaxRestarts == 0 {
		s.MaxRestarts = 5
	}
	if s.MaxTime == 0 {
		s.MaxTime = 15 * time.Second
	}
	if s.Log == nil {
		s.Log = func(msg interface{}) {
			log.Printf("%s: %v", s.Name, msg)
		}
	}
	s.name = s.Name
	s.maxrestarts = s.MaxRestarts
	s.maxtime = s.MaxTime
	s.log = s.Log
	s.added = make(chan struct{})
	s.cancelations = make(map[string]context.CancelFunc)
	s.services = make(map[string]ServiceSpecification)
	s.terminations = make(map[string]context.CancelFunc)
	s.mu.Unlock()
}
func (s *Supervisor) shouldRestart() bool {
	if s.maxrestarts == AlwaysRestart {
		return true
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	if time.Since(s.lastRestart) > s.maxtime {
		s.restarts = 0
	}
	s.lastRestart = time.Now()
	s.restarts++
	return s.restarts < s.maxrestarts
}
func (s *Supervisor) Cancelations() map[string]context.CancelFunc {
	svclist := make(map[string]context.CancelFunc)
	s.mu.Lock()
	for k, v := range s.cancelations {
		svclist[k] = v
	}
	s.mu.Unlock()
	return svclist
}