func (s *Supervisor) Add(service Service) ServiceToken {
	if s == nil {
		panic("can't add service to nil *suture.Supervisor")
	}
	if hasSupervisor, isHaveSupervisor := service.(HasSupervisor); isHaveSupervisor {
		supervisor := hasSupervisor.GetSupervisor()
		if supervisor != nil {
			supervisor.spec.EventHook = s.spec.EventHook
		}
	}
	s.m.Lock()
	if s.state == notRunning {
		id := s.serviceCounter
		s.serviceCounter++
		s.services[id] = serviceWithName{service, serviceName(service)}
		s.restartQueue = append(s.restartQueue, id)
		s.m.Unlock()
		return ServiceToken{uint64(s.id)<<32 | uint64(id)}
	}
	s.m.Unlock()
	response := make(chan serviceID)
	if s.sendControl(addService{service, serviceName(service), response}) != nil {
		return ServiceToken{}
	}
	return ServiceToken{uint64(s.id)<<32 | uint64(<-response)}
}
/*
Add adds a service to this supervisor.

If the supervisor is currently running, the service will be started
immediately. If the supervisor has not been started yet, the service
will be started when the supervisor is. If the supervisor was already stopped,
this is a no-op returning an empty service-token.

The returned ServiceID may be passed to the Remove method of the Supervisor
to terminate the service.

As a special behavior, if the service added is itself a supervisor, the
supervisor being added will copy the EventHook function from the Supervisor it
is being added to. This allows factoring out providing a Supervisor
from its logging. This unconditionally overwrites the child Supervisor's
logging functions.
package suture
import (
	"context"
	"errors"
	"fmt"
	"log"
	"math"
	"math/rand"
	"runtime"
	"sync"
	"time"
)
const (
	notRunning = iota
	normal
	paused
	terminated
)
type supervisorID uint32
type serviceID uint32
var ErrSupervisorNotRunning = errors.New("supervisor not running")
type Supervisor struct {
	Name string
	spec Spec
	services             map[serviceID]serviceWithName
	cancellations        map[serviceID]context.CancelFunc
	servicesShuttingDown map[serviceID]serviceWithName
	lastFail             time.Time
	failures             float64
	restartQueue         []serviceID
	serviceCounter       serviceID
	control              chan supervisorMessage
	notifyServiceDone    chan serviceID
	resumeTimer          <-chan time.Time
	liveness             chan struct{}
	ctxMutex sync.Mutex
	ctx      context.Context
	ctxCancel func()
	getNow       func() time.Time
	getAfterChan func(time.Duration) <-chan time.Time
	m sync.Mutex
	unstoppedServiceReport UnstoppedServiceReport
	id    supervisorID
	state uint8
}
func New(name string, spec Spec) *Supervisor {
	spec.configureDefaults(name)
	return &Supervisor{
		name,
		spec,
		make(map[serviceID]serviceWithName),
		make(map[serviceID]context.CancelFunc),
		make(map[serviceID]serviceWithName),
		time.Time{},
		0,
		make([]serviceID, 0, 1),
		0,
		make(chan supervisorMessage),
		make(chan serviceID),
		make(chan time.Time),
		make(chan struct{}),
		sync.Mutex{},
		nil,
		nil,
		time.Now,
		time.After,
		sync.Mutex{},
		nil,
		nextSupervisorID(),
		notRunning,
	}
}
func serviceName(service Service) (serviceName string) {
	stringer, canStringer := service.(fmt.Stringer)
	if canStringer {
		serviceName = stringer.String()
	} else {
		serviceName = fmt.Sprintf("%#v", service)
	}
	return
}
func NewSimple(name string) *Supervisor {
	return New(name, Spec{})
}
type HasSupervisor interface {
	GetSupervisor() *Supervisor
}
func (s *Supervisor) GetSupervisor() *Supervisor {
	return s
}