Skip to content
Snippets Groups Projects
Commit 97b9c732 authored by ale's avatar ale
Browse files

Rename some methods for clarity, and add more comments

parent 5f72b930
No related branches found
No related tags found
No related merge requests found
......@@ -91,9 +91,9 @@ func (d *debugServer) handleDebugHome(w http.ResponseWriter, req *http.Request)
}
errsOnly := (req.FormValue("errs") == "y")
if errsOnly {
d.store.DoErrs(appendResult)
d.store.EachErrs(appendResult)
} else {
d.store.DoOk(appendResult)
d.store.Each(appendResult)
}
debugHomeTpl.Execute(w, map[string]interface{}{
......@@ -129,6 +129,6 @@ func (s *dumpResultStore) Push(r *probes.Result) {
}
}
func (s *dumpResultStore) DoOk(func(*probes.Result)) {}
func (s *dumpResultStore) DoErrs(func(*probes.Result)) {}
func (s *dumpResultStore) Each(func(*probes.Result)) {}
func (s *dumpResultStore) EachErrs(func(*probes.Result)) {}
func (s *dumpResultStore) Find(string) *probes.Result { return nil }
......@@ -19,6 +19,7 @@ var (
defaultTimeout = 5 * time.Minute
)
// SpecCommon holds the parameters common to all probe specifications.
type SpecCommon struct {
Type string `json:"type"`
Name string `json:"name"`
......@@ -42,10 +43,13 @@ type config struct {
Probes []*rawSpec `json:"probes"`
}
// ProbeImpl is the probe-specific implementation interface.
type ProbeImpl interface {
RunProbe(context.Context, *log.Logger) error
}
// Spec is the generic interface for probe implementation factory
// functions.
type Spec interface {
Build(map[string]interface{}) (ProbeImpl, error)
}
......@@ -58,6 +62,26 @@ func RegisterProbeType(ptype string, pfunc probeParserFunc) {
probeRegistry[ptype] = pfunc
}
// ParseConfig parses a JSON-encoded configuration and returns a list of
// Probe objects that can be executed or sent to the scheduler.
//
// Configuration parsing has a few phases: decoding the configuration
// itself is a relatively complex task, as we are implementing
// polymorphysm on probe definitions (via their "params"
// attribute).This requires a multi-level approach in Go, where JSON
// parsing is split into generic / specific stages, with the latter
// delegated to a type-specific parser accessed via a global
// registry. The result of this process is a "template" probe called a
// Spec, which has to be an interface type because the actual struct
// definition is private to the specific probe implementation.
//
// Then, parameterization is applied, potentially generating multiple
// Probes from each Spec. Variables are expanded, and all necessary
// information is bound together in the runtime-ready Probe object.
// The variable expansion process is reflect-heavy but is only
// performed once at the start of the process. The resulting Probe
// objects are minimal and lean.
//
func ParseConfig(data []byte, resultStore ResultStore) ([]*Probe, error) {
var cfg config
if err := json.Unmarshal(data, &cfg); err != nil {
......@@ -148,6 +172,9 @@ func checkUniqueness(probes []*Probe) error {
return nil
}
// A Probe holds all the runtime information necessary to run a single
// probe, combining the SpecCommon parameters with a ProbeImpl to
// actually execute the probe.
type Probe struct {
spec SpecCommon
impl ProbeImpl
......@@ -157,6 +184,7 @@ type Probe struct {
vars map[string]interface{}
}
// Name is a convenience function to return the probe name.
func (p *Probe) Name() string { return p.spec.Name }
// Interval satisfies the scheduler.PeriodicEvent interface.
......
......@@ -6,6 +6,7 @@ import (
"time"
)
// Result of the execution of a probe.
type Result struct {
ID string
Spec SpecCommon
......@@ -21,10 +22,17 @@ func (r *Result) String() string {
return fmt.Sprintf("%s(%s)", r.Spec.Name, r.ID)
}
// ResultStore keeps the most recent probe results in storage, and
// allows access to them (mostly for debugging purposes, as this part
// isn't required by the prober functionality). The results buffer has
// a fixed size, so older results will be dropped as more recent ones
// come in. Failures are kept in a separate buffer, with the hope of
// keeping errors around for longer for inspection purposes, even
// after they've recovered.
type ResultStore interface {
Push(*Result)
DoOk(func(*Result))
DoErrs(func(*Result))
Each(func(*Result))
EachErrs(func(*Result))
Find(string) *Result
}
......@@ -84,13 +92,13 @@ func (r *memResultStore) Push(result *Result) {
r.mx.Unlock()
}
func (r *memResultStore) DoOk(f func(*Result)) {
func (r *memResultStore) Each(f func(*Result)) {
r.mx.Lock()
r.last.Each(f)
r.mx.Unlock()
}
func (r *memResultStore) DoErrs(f func(*Result)) {
func (r *memResultStore) EachErrs(f func(*Result)) {
r.mx.Lock()
r.errs.Each(f)
r.mx.Unlock()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment