Example #1
0
func TestHandleIncrHitBucket(t *testing.T) {
	namespace = randomNamespace()
	listener.HandleEvent(events.NewTokensServedEvent(namespace, "incr-hit", true, 1, 0))
	listener.HandleEvent(events.NewTokensServedEvent(namespace, "incr-hit", true, 3, 0))
	listener.HandleEvent(events.NewTokensServedEvent(namespace, "incr-hit", true, 1, 0))
	scores := listener.Get(namespace, "incr-hit")

	if scores.Hits != 5 || scores.Misses != 0 {
		t.Fatalf("Bucket score was not accurate: %+v != [Hits=5, Misses=0]", scores)
	}
}
Example #2
0
func TestHandleIncrHitBucket(t *testing.T) {
	listener = stats.NewMemoryStatsListener()
	listener.HandleEvent(events.NewTokensServedEvent("test", "dyn", true, 1, 0))
	listener.HandleEvent(events.NewTokensServedEvent("test", "dyn", true, 3, 0))
	listener.HandleEvent(events.NewTokensServedEvent("test", "dyn", true, 1, 0))
	scores := listener.Get("test", "dyn")

	if scores.Hits != 5 || scores.Misses != 0 {
		t.Fatalf("Bucket score was not accurate: %+v != [Hits=5, Misses=0]", scores)
	}
}
Example #3
0
func TestTop10Hits(t *testing.T) {
	namespace = randomNamespace()
	listener.HandleEvent(events.NewTokensServedEvent(namespace, "hits-dyn-1", true, 3, 0))
	listener.HandleEvent(events.NewTokensServedEvent(namespace, "hits-dyn-2", true, 10, 0))
	listener.HandleEvent(events.NewTokensServedEvent(namespace, "hits-dyn-3", true, 1, 0))

	hits := listener.TopHits(namespace)
	correctHits := []*stats.BucketScore{
		&stats.BucketScore{"hits-dyn-2", 10},
		&stats.BucketScore{"hits-dyn-1", 3},
		&stats.BucketScore{"hits-dyn-3", 1}}

	if !reflect.DeepEqual(hits, correctHits) {
		t.Fatalf("Hits top10 is not correct %+v", hits)
	}
}
Example #4
0
func TestTop10Hits(t *testing.T) {
	listener = stats.NewMemoryStatsListener()
	listener.HandleEvent(events.NewTokensServedEvent("test", "dyn-1", true, 3, 0))
	listener.HandleEvent(events.NewTokensServedEvent("test", "dyn-2", true, 10, 0))
	listener.HandleEvent(events.NewTokensServedEvent("test", "dyn-3", true, 1, 0))

	hits := listener.TopHits("test")
	correctHits := []*stats.BucketScore{
		&stats.BucketScore{"dyn-2", 10},
		&stats.BucketScore{"dyn-1", 3},
		&stats.BucketScore{"dyn-3", 1}}

	if !reflect.DeepEqual(hits, correctHits) {
		t.Fatalf("Hits top10 is not correct %+v", hits)
	}
}
Example #5
0
func TestHandleNewHitBucket(t *testing.T) {
	namespace = randomNamespace()
	ev := events.NewTokensServedEvent(namespace, "new-hit-dyn", true, 1, 0)
	listener.HandleEvent(ev)
	scores := listener.Get(namespace, "new-hit-dyn")

	if scores.Hits != 1 || scores.Misses != 0 {
		t.Fatalf("Bucket score was not accurate: %+v != [Hits=1, Misses=0]", scores)
	}

	ev = events.NewTokensServedEvent(namespace, "nondyn", false, 1, 0)
	listener.HandleEvent(ev)
	scores = listener.Get(namespace, "nondyn")

	if scores.Hits != 0 || scores.Misses != 0 {
		t.Fatalf("Non-dynamic bucket score was not accurate: %+v != [Hits=0, Misses=0]", scores)
	}

	scores = listener.Get(namespace, "nondyn")

	if scores.Hits != 0 || scores.Misses != 0 {
		t.Fatalf("Nonexisting namespace was not accurate: %+v != [Hits=0, Misses=0]", scores)
	}
}
Example #6
0
func (s *server) Allow(namespace, name string, tokensRequested int64, maxWaitMillisOverride int64, maxWaitTimeOverride bool) (time.Duration, error) {
	s.RLock()
	b, e := s.bucketContainer.FindBucket(namespace, name)
	s.RUnlock()

	if e != nil {
		// Attempted to create a dynamic bucket and failed.
		s.Emit(events.NewBucketMissedEvent(namespace, name, true))
		return 0, newError("Cannot create dynamic bucket "+config.FullyQualifiedName(namespace, name), ER_TOO_MANY_BUCKETS)
	}

	if b == nil {
		s.Emit(events.NewBucketMissedEvent(namespace, name, false))
		return 0, newError("No such bucket "+config.FullyQualifiedName(namespace, name), ER_NO_BUCKET)
	}

	if b.Config().MaxTokensPerRequest < tokensRequested && b.Config().MaxTokensPerRequest > 0 {
		s.Emit(events.NewTooManyTokensRequestedEvent(namespace, name, b.Dynamic(), tokensRequested))
		return 0, newError(fmt.Sprintf("Too many tokens requested. Bucket %v:%v, tokensRequested=%v, maxTokensPerRequest=%v",
			namespace, name, tokensRequested, b.Config().MaxTokensPerRequest),
			ER_TOO_MANY_TOKENS_REQUESTED)
	}

	maxWaitTime := time.Millisecond
	if maxWaitTimeOverride && maxWaitMillisOverride < b.Config().WaitTimeoutMillis {
		// Use the max wait time override from the request.
		maxWaitTime *= time.Duration(maxWaitMillisOverride)
	} else {
		// Fall back to the max wait time configured on the bucket.
		maxWaitTime *= time.Duration(b.Config().WaitTimeoutMillis)
	}

	w, success := b.Take(tokensRequested, maxWaitTime)

	if !success {
		// Could not claim tokens within the given max wait time
		s.Emit(events.NewTimedOutEvent(namespace, name, b.Dynamic(), tokensRequested))
		return 0, newError(fmt.Sprintf("Timed out waiting on %v:%v", namespace, name), ER_TIMEOUT)
	}

	// The only positive result
	s.Emit(events.NewTokensServedEvent(namespace, name, b.Dynamic(), tokensRequested, w))
	return w, nil
}