package probes import ( "container/ring" "fmt" "sync" "time" ) type Result struct { ID string Spec SpecCommon Ok bool Start time.Time Duration time.Duration Logs string } // Nice displayable string. func (r *Result) String() string { return fmt.Sprintf("%s(%s)", r.Spec.Name, r.ID) } type ResultStore interface { Push(*Result) DoOk(func(*Result)) DoErrs(func(*Result)) Find(string) *Result } type memResultStore struct { mx sync.Mutex last *ring.Ring errs *ring.Ring } func NewResultStore(numOk, numErrs int) ResultStore { return &memResultStore{ last: ring.New(numOk), errs: ring.New(numErrs), } } func (r *memResultStore) Push(result *Result) { r.mx.Lock() r.last.Value = result r.last = r.last.Next() if !result.Ok { r.errs.Value = result r.errs = r.errs.Next() } r.mx.Unlock() } func (r *memResultStore) DoOk(f func(*Result)) { r.mx.Lock() r.last.Do(func(r interface{}) { f(r.(*Result)) }) r.mx.Unlock() } func (r *memResultStore) DoErrs(f func(*Result)) { r.mx.Lock() r.errs.Do(func(r interface{}) { f(r.(*Result)) }) r.mx.Unlock() } func (r *memResultStore) Find(id string) (out *Result) { r.mx.Lock() r.last.Do(func(r interface{}) { result := r.(*Result) if result.ID == id { out = result } }) r.mx.Unlock() return }