// HandleEvent is implemented for stats.Listener // HandleEvent consumes dynamic bucket events (see events.Event) func (l *redisListener) HandleEvent(event events.Event) { if !event.Dynamic() { return } var key string var numTokens int64 = 1 switch event.EventType() { case events.EVENT_BUCKET_MISS: key = "misses" case events.EVENT_TOKENS_SERVED: numTokens = event.NumTokens() key = "hits" default: return } namespace := statsNamespace(key, event.Namespace()) bucket := event.BucketName() var incr *redis.FloatCmd _, err := l.client.Pipelined(func(pipe *redis.Pipeline) error { incr = pipe.ZIncrBy(namespace, float64(numTokens), bucket) pipe.ExpireAt(namespace, nearestHour()) return nil }) if err != nil || incr.Err() != nil { logging.Printf("RedisStatsListener.HandleEvent error (%s, %s, %d) %v, %v", namespace, bucket, numTokens, err, incr.Err()) } }
func checkEvent(namespace, name string, dyn bool, eventType events.EventType, tokens int64, waitTime time.Duration, actual events.Event, t *testing.T) { if actual == nil { t.Fatalf("Expecting event; was nil.") } if actual.Namespace() != namespace { t.Fatalf("Event should have namespace '%v'. Was '%v'. Event %+v.", namespace, actual.Namespace(), actual) } if actual.BucketName() != name { t.Fatalf("Event should have bucket name '%v'. Was '%v'. Event %+v.", name, actual.BucketName(), actual) } if actual.Dynamic() != dyn { t.Fatalf("Event should have dynamic='%v'. Was '%v'. Event %+v.", dyn, actual.Dynamic(), actual) } if actual.EventType() != eventType { t.Fatalf("Event should have type '%v'. Was '%v'. Event %+v.", eventType, actual.EventType(), actual) } if actual.NumTokens() != tokens { t.Fatalf("Event should have tokens '%v'. Was '%v'. Event %+v.", tokens, actual.NumTokens(), actual) } if actual.WaitTime() != waitTime { t.Fatalf("Event should have wait time '%v'. Was '%v'. Event %+v.", waitTime, actual.WaitTime(), actual) } }
// HandleEvent is implemented for stats.Listener // HandleEvent consumes dynamic bucket events (see events.Event) func (l *memoryListener) HandleEvent(event events.Event) { if !event.Dynamic() { return } namespace := event.Namespace() if _, ok := l.namespaces[namespace]; !ok { l.namespaces[namespace] = &namespaceStats{ make(map[string]*BucketScore), make(map[string]*BucketScore)} } stats := l.namespaces[namespace] var statsBucket map[string]*BucketScore var numTokens int64 = 1 switch event.EventType() { case events.EVENT_BUCKET_MISS: statsBucket = stats.misses case events.EVENT_TOKENS_SERVED: numTokens = event.NumTokens() statsBucket = stats.hits default: return } key := event.BucketName() if _, ok := statsBucket[key]; !ok { statsBucket[key] = &BucketScore{key, 0} } statsBucket[key].Score += numTokens }