Пример #1
0
func (bf *MockBucketFactory) bucket(namespace, name string) *MockBucket {
	fqn := config.FullyQualifiedName(namespace, name)
	bucket := bf.buckets[fqn]
	if bucket == nil {
		panic(fmt.Sprintf("No such bucket %v", fqn))
	}
	return bucket
}
Пример #2
0
func (bf *MockBucketFactory) NewBucket(namespace string, bucketName string, cfg *pbconfig.BucketConfig, dyn bool) Bucket {
	b := &MockBucket{sync.RWMutex{}, 0, namespace, bucketName, dyn, cfg}
	if bf.buckets == nil {
		bf.buckets = make(map[string]*MockBucket)
	}

	bf.buckets[config.FullyQualifiedName(namespace, bucketName)] = b
	return b
}
Пример #3
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
}
Пример #4
0
func (bf *bucketFactory) NewBucket(namespace, bucketName string, cfg *pbconfig.BucketConfig, dyn bool) quotaservice.Bucket {
	// fill rate is tokens-per-second.
	bucket := &tokenBucket{
		dynamic:            dyn,
		cfg:                cfg,
		nanosBetweenTokens: 1e9 / cfg.FillRate,
		accumulatedTokens:  cfg.Size, // Start full
		fullName:           config.FullyQualifiedName(namespace, bucketName),
		waitTimer:          make(chan *waitTimeReq),
		closer:             make(chan struct{})}

	go bucket.waitTimeLoop()

	return bucket
}