Forráskód Böngészése

Synchronization for Registry objects.

Richard Crowley 14 éve
szülő
commit
f55f4f8f54
3 módosított fájl, 122 hozzáadás és 68 törlés
  1. 12 12
      log.go
  2. 98 44
      registry.go
  3. 12 12
      syslog.go

+ 12 - 12
log.go

@@ -7,20 +7,20 @@ import (
 
 func Log(r Registry, interval int, l *log.Logger) {
 	for {
-		for name, c := range r.Counters() {
+		r.EachCounter(func(name string, c Counter) {
 			l.Printf("counter %s\n", name)
 			l.Printf("  count:       %9d\n", c.Count())
-		}
-		for name, g := range r.Gauges() {
+		})
+		r.EachGauge(func(name string, g Gauge) {
 			l.Printf("gauge %s\n", name)
 			l.Printf("  value:       %9d\n", g.Value())
-		}
+		})
 		r.RunHealthchecks()
-		for name, h := range r.Healthchecks() {
+		r.EachHealthcheck(func(name string, h Healthcheck) {
 			l.Printf("healthcheck %s\n", name)
 			l.Printf("  error:       %v\n", h.Error())
-		}
-		for name, h := range r.Histograms() {
+		})
+		r.EachHistogram(func(name string, h Histogram) {
 			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
 			l.Printf("histogram %s\n", name)
 			l.Printf("  count:       %9d\n", h.Count())
@@ -33,16 +33,16 @@ func Log(r Registry, interval int, l *log.Logger) {
 			l.Printf("  95%%:         %12.2f\n", ps[2])
 			l.Printf("  99%%:         %12.2f\n", ps[3])
 			l.Printf("  99.9%%:       %12.2f\n", ps[4])
-		}
-		for name, m := range r.Meters() {
+		})
+		r.EachMeter(func(name string, m Meter) {
 			l.Printf("meter %s\n", name)
 			l.Printf("  count:       %9d\n", m.Count())
 			l.Printf("  1-min rate:  %12.2f\n", m.Rate1())
 			l.Printf("  5-min rate:  %12.2f\n", m.Rate5())
 			l.Printf("  15-min rate: %12.2f\n", m.Rate15())
 			l.Printf("  mean rate:   %12.2f\n", m.RateMean())
-		}
-		for name, t := range r.Timers() {
+		})
+		r.EachTimer(func(name string, t Timer) {
 			ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
 			l.Printf("timer %s\n", name)
 			l.Printf("  count:       %9d\n", t.Count())
@@ -59,7 +59,7 @@ func Log(r Registry, interval int, l *log.Logger) {
 			l.Printf("  5-min rate:  %12.2f\n", t.Rate5())
 			l.Printf("  15-min rate: %12.2f\n", t.Rate15())
 			l.Printf("  mean rate:   %12.2f\n", t.RateMean())
-		}
+		})
 		time.Sleep(int64(1e9) * int64(interval))
 	}
 }

+ 98 - 44
registry.go

@@ -1,22 +1,22 @@
 package metrics
 
-type Registry interface{
+import "sync"
 
-	Counters() map[string]Counter
-	Gauges() map[string]Gauge
-	Healthchecks() map[string]Healthcheck
-	Histograms() map[string]Histogram
-	Meters() map[string]Meter
-	Timers() map[string]Timer
+type Registry interface{
 
-	RunHealthchecks()
+	EachCounter(func(string, Counter))
+	EachGauge(func(string, Gauge))
+	EachHealthcheck(func(string, Healthcheck))
+	EachHistogram(func(string, Histogram))
+	EachMeter(func(string, Meter))
+	EachTimer(func(string, Timer))
 
-	GetCounter(string) (Counter, bool)
-	GetGauge(string) (Gauge, bool)
-	GetHealthcheck(string) (Healthcheck, bool)
-	GetHistogram(string) (Histogram, bool)
-	GetMeter(string) (Meter, bool)
-	GetTimer(string) (Timer, bool)
+	GetCounter(string) Counter
+	GetGauge(string) Gauge
+	GetHealthcheck(string) Healthcheck
+	GetHistogram(string) Histogram
+	GetMeter(string) Meter
+	GetTimer(string) Timer
 
 	RegisterCounter(string, Counter)
 	RegisterGauge(string, Gauge)
@@ -25,6 +25,8 @@ type Registry interface{
 	RegisterMeter(string, Meter)
 	RegisterTimer(string, Timer)
 
+	RunHealthchecks()
+
 	UnregisterCounter(string)
 	UnregisterGauge(string)
 	UnregisterHealthcheck(string)
@@ -35,6 +37,7 @@ type Registry interface{
 }
 
 type registry struct {
+	mutex *sync.Mutex
 	counters map[string]Counter
 	gauges map[string]Gauge
 	healthchecks map[string]Healthcheck
@@ -45,6 +48,7 @@ type registry struct {
 
 func NewRegistry() Registry {
 	return &registry {
+		&sync.Mutex{},
 		make(map[string]Counter),
 		make(map[string]Gauge),
 		make(map[string]Healthcheck),
@@ -54,108 +58,158 @@ func NewRegistry() Registry {
 	}
 }
 
-func (r *registry) Counters() map[string]Counter {
-	return r.counters
+func (r *registry) EachCounter(f func(string, Counter)) {
+	r.mutex.Lock()
+	for name, c := range r.counters { f(name, c) }
+	r.mutex.Unlock()
 }
 
-func (r *registry) Gauges() map[string]Gauge {
-	return r.gauges
+func (r *registry) EachGauge(f func(string, Gauge)) {
+	r.mutex.Lock()
+	for name, g := range r.gauges { f(name, g) }
+	r.mutex.Unlock()
 }
 
-func (r *registry) Healthchecks() map[string]Healthcheck {
-	return r.healthchecks
+func (r *registry) EachHealthcheck(f func(string, Healthcheck)) {
+	r.mutex.Lock()
+	for name, h := range r.healthchecks { f(name, h) }
+	r.mutex.Unlock()
 }
 
-func (r *registry) Histograms() map[string]Histogram {
-	return r.histograms
+func (r *registry) EachHistogram(f func(string, Histogram)) {
+	r.mutex.Lock()
+	for name, h := range r.histograms { f(name, h) }
+	r.mutex.Unlock()
 }
 
-func (r *registry) Meters() map[string]Meter {
-	return r.meters
+func (r *registry) EachMeter(f func(string, Meter)) {
+	r.mutex.Lock()
+	for name, m := range r.meters { f(name, m) }
+	r.mutex.Unlock()
 }
 
-func (r *registry) Timers() map[string]Timer {
-	return r.timers
+func (r *registry) EachTimer(f func(string, Timer)) {
+	r.mutex.Lock()
+	for name, t := range r.timers { f(name, t) }
+	r.mutex.Unlock()
 }
 
 func (r *registry) RunHealthchecks() {
+	r.mutex.Lock()
 	for _, h := range r.healthchecks { h.Check() }
+	r.mutex.Unlock()
 }
 
-func (r *registry) GetCounter(name string) (Counter, bool) {
-	c, ok := r.counters[name]
-	return c, ok
+func (r *registry) GetCounter(name string) Counter {
+	r.mutex.Lock()
+	c := r.counters[name]
+	r.mutex.Unlock()
+	return c
 }
 
-func (r *registry) GetGauge(name string) (Gauge, bool) {
-	g, ok := r.gauges[name]
-	return g, ok
+func (r *registry) GetGauge(name string) Gauge {
+	r.mutex.Lock()
+	g := r.gauges[name]
+	r.mutex.Unlock()
+	return g
 }
 
-func (r *registry) GetHealthcheck(name string) (Healthcheck, bool) {
-	h, ok := r.healthchecks[name]
-	return h, ok
+func (r *registry) GetHealthcheck(name string) Healthcheck {
+	r.mutex.Lock()
+	h := r.healthchecks[name]
+	r.mutex.Unlock()
+	return h
 }
 
-func (r *registry) GetHistogram(name string) (Histogram, bool) {
-	h, ok := r.histograms[name]
-	return h, ok
+func (r *registry) GetHistogram(name string) Histogram {
+	r.mutex.Lock()
+	h := r.histograms[name]
+	r.mutex.Unlock()
+	return h
 }
 
-func (r *registry) GetMeter(name string) (Meter, bool) {
-	m, ok := r.meters[name]
-	return m, ok
+func (r *registry) GetMeter(name string) Meter {
+	r.mutex.Lock()
+	m := r.meters[name]
+	r.mutex.Unlock()
+	return m
 }
 
-func (r *registry) GetTimer(name string) (Timer, bool) {
-	t, ok := r.timers[name]
-	return t, ok
+func (r *registry) GetTimer(name string) Timer {
+	r.mutex.Lock()
+	t := r.timers[name]
+	r.mutex.Unlock()
+	return t
 }
 
 func (r *registry) RegisterCounter(name string, c Counter) {
+	r.mutex.Lock()
 	r.counters[name] = c
+	r.mutex.Unlock()
 }
 
 func (r *registry) RegisterGauge(name string, g Gauge) {
+	r.mutex.Lock()
 	r.gauges[name] = g
+	r.mutex.Unlock()
 }
 
 func (r *registry) RegisterHealthcheck(name string, h Healthcheck) {
+	r.mutex.Lock()
 	r.healthchecks[name] = h
+	r.mutex.Unlock()
 }
 
 func (r *registry) RegisterHistogram(name string, h Histogram) {
+	r.mutex.Lock()
 	r.histograms[name] = h
+	r.mutex.Unlock()
 }
 
 func (r *registry) RegisterMeter(name string, m Meter) {
+	r.mutex.Lock()
 	r.meters[name] = m
+	r.mutex.Unlock()
 }
 
 func (r *registry) RegisterTimer(name string, t Timer) {
+	r.mutex.Lock()
 	r.timers[name] = t
+	r.mutex.Unlock()
 }
 
 func (r *registry) UnregisterCounter(name string) {
+	r.mutex.Lock()
 	r.counters[name] = nil, false
+	r.mutex.Unlock()
 }
 
 func (r *registry) UnregisterGauge(name string) {
+	r.mutex.Lock()
 	r.gauges[name] = nil, false
+	r.mutex.Unlock()
 }
 
 func (r *registry) UnregisterHealthcheck(name string) {
+	r.mutex.Lock()
 	r.healthchecks[name] = nil, false
+	r.mutex.Unlock()
 }
 
 func (r *registry) UnregisterHistogram(name string) {
+	r.mutex.Lock()
 	r.histograms[name] = nil, false
+	r.mutex.Unlock()
 }
 
 func (r *registry) UnregisterMeter(name string) {
+	r.mutex.Lock()
 	r.meters[name] = nil, false
+	r.mutex.Unlock()
 }
 
 func (r *registry) UnregisterTimer(name string) {
+	r.mutex.Lock()
 	r.timers[name] = nil, false
+	r.mutex.Unlock()
 }

+ 12 - 12
syslog.go

@@ -8,17 +8,17 @@ import (
 
 func Syslog(r Registry, interval int, w *syslog.Writer) {
 	for {
-		for name, c := range r.Counters() {
+		r.EachCounter(func(name string, c Counter) {
 			w.Info(fmt.Sprintf("counter %s: count: %d", name, c.Count()))
-		}
-		for name, g := range r.Gauges() {
+		})
+		r.EachGauge(func(name string, g Gauge) {
 			w.Info(fmt.Sprintf("gauge %s: value: %d", name, g.Value()))
-		}
+		})
 		r.RunHealthchecks()
-		for name, h := range r.Healthchecks() {
+		r.EachHealthcheck(func(name string, h Healthcheck) {
 			w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, h.Error()))
-		}
-		for name, h := range r.Histograms() {
+		})
+		r.EachHistogram(func(name string, h Histogram) {
 			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
 			w.Info(fmt.Sprintf(
 				"histogram %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f",
@@ -34,8 +34,8 @@ func Syslog(r Registry, interval int, w *syslog.Writer) {
 				ps[3],
 				ps[4],
 			))
-		}
-		for name, m := range r.Meters() {
+		})
+		r.EachMeter(func(name string, m Meter) {
 			w.Info(fmt.Sprintf(
 				"meter %s: count: %d 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
 				name,
@@ -45,8 +45,8 @@ func Syslog(r Registry, interval int, w *syslog.Writer) {
 				m.Rate15(),
 				m.RateMean(),
 			))
-		}
-		for name, t := range r.Timers() {
+		})
+		r.EachTimer(func(name string, t Timer) {
 			ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
 			w.Info(fmt.Sprintf(
 				"timer %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
@@ -66,7 +66,7 @@ func Syslog(r Registry, interval int, w *syslog.Writer) {
 				t.Rate15(),
 				t.RateMean(),
 			))
-		}
+		})
 		time.Sleep(int64(1e9) * int64(interval))
 	}
 }