package main import ( "sync" "time" ) type Life struct { shutdown chan struct{} wg *sync.WaitGroup errChan chan error } func NewLife() *Life { return &Life{ shutdown: make(chan struct{}), wg: new(sync.WaitGroup), errChan: make(chan error), } } func (l *Life) Beget() *Life { l.wg.Add(1) return l } func (l *Life) Fail(err error) { l.errChan <- err } func (l *Life) Failed() chan error { return l.errChan } func (l *Life) Kill() { close(l.shutdown) } func (l *Life) IsDead() chan struct{} { return l.shutdown } func (l *Life) Died() { l.wg.Done() } func (l *Life) Wait(t time.Duration) bool { done := make(chan struct{}) go func() { l.wg.Wait() done <- struct{}{} }() select { case <-done: return true case <-time.After(t): return false } }