Skip to content
Snippets Groups Projects
results.go 1.29 KiB
Newer Older
ale's avatar
ale committed
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
}