// NewExpiringBuckets 带过期时间
// @param max 每个周期的最大连接数
// @param ttl 周期
// @param bucketDefaultExpirationTTL 默认有效时长
// @param bucketExpireJobInterval 默认清理周期
333960
func NewExpiringBuckets(max int64, ttl, bucketDefaultExpirationTTL, bucketExpireJobInterval time.Duration) *config.Limiter {
	return config.NewLimiterExpiringBuckets(max, ttl, bucketDefaultExpirationTTL, bucketExpireJobInterval)
}
1039942
func DefaultControllerRateLimiter() RateLimiter {
	return NewMaxOfRateLimiter(
		NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
		// 10 qps, 100 bucket size.  This is only for retry speed and its only the overall factor (not per item)
		&BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
	)
}
319964
func (c CreateLeaseReq) ExpirationTime(start time.Time) time.Time {
	return start.Add(c.MaxTimeDur())
}
1029844
func (a *MaxBucketAggregation) BucketsPath(bucketsPaths ...string) *MaxBucketAggregation {
	a.bucketsPaths = append(a.bucketsPaths, bucketsPaths...)
	return a
}
1057997
func NewLimitedQueue(max int) Queue {
	return Queue{queue: make([]interface{}, 0, max), maxLen: max, mode: modeNormal}
}
931293
func (i *itemWithExp) randomlyExpired(ctx context.Context, now time.Time, threshold time.Duration) bool {
	if i.exp.IsZero() {
		return false // never expires
	}

	ttl := i.exp.Sub(now)
	if ttl > threshold {
		return false // far from expiration, no need to enable randomization
	}

	// TODO(vadimsh): The choice of distribution here was made arbitrary. Some
	// literature suggests to use exponential distribution instead, but it's not
	// clear how to pick parameters for it. In practice what we do here seems good
	// enough. On each check we randomly expire the item with probability
	// p = (threshold - ttl) / threshold. Closer the item to its true expiration
	// (ttl is smaller), higher the probability.
	rnd := time.Duration(mathrand.Int63n(ctx, int64(threshold)))
	return rnd > ttl
}
1262345
func (v *vaultClient) extendExpiration(ttlSeconds int) {
	v.currentExpirationLock.Lock()
	v.currentExpiration = time.Now().Add(time.Duration(ttlSeconds) * time.Second)
	v.currentExpirationLock.Unlock()
}
239902
func (c *CmdChatSetRetention) parseExpireAgeLimited(s string) (gregor1.DurationSec, error) {
	var d time.Duration
	switch s {
	case "1d", "24h":
		d = 24 * time.Hour
	case "7d", "1w":
		d = 7 * 24 * time.Hour
	case "30d", "1m":
		d = 30 * 24 * time.Hour
	case "3m":
		d = 90 * 24 * time.Hour
	case "12m", "1y":
		d = 365 * 24 * time.Hour
	default:
		return 0, fmt.Errorf("invalid expiration age: %v", s)
	}
	return gregor1.DurationSec(d.Seconds()), nil
}
172250
func (l *Limiter) LimitReachedWithCustomTokenBucketTTL(key string, tokenBucketTTL time.Duration) bool {
	if l.isUsingTokenBucketsWithTTL() {
		return l.limitReachedWithCustomTokenBucketTTL(key, tokenBucketTTL)
	}
	return l.limitReachedNoTokenBucketTTL(key)
}
101939
func NewExpirationManager(c *Core, view *BarrierView, e ExpireLeaseStrategy, logger log.Logger) *ExpirationManager {
	exp := &ExpirationManager{
		core:       c,
		router:     c.router,
		idView:     view.SubView(leaseViewPrefix),
		tokenView:  view.SubView(tokenViewPrefix),
		tokenStore: c.tokenStore,
		logger:     logger,
		pending:    make(map[string]pendingInfo),
		tidyLock:   new(int32),

		// new instances of the expiration manager will go immediately into
		// restore mode
		restoreMode:  new(int32),
		restoreLocks: locksutil.CreateLocks(),
		quitCh:       make(chan struct{}),

		coreStateLock:     &c.stateLock,
		quitContext:       c.activeContext,
		leaseCheckCounter: new(uint32),

		logLeaseExpirations: os.Getenv("VAULT_SKIP_LOGGING_LEASE_EXPIRATIONS") == "",
		expireFunc:          e,
	}
	*exp.restoreMode = 1

	if exp.logger == nil {
		opts := log.LoggerOptions{Name: "expiration_manager"}
		exp.logger = log.New(&opts)
	}

	return exp
}
419186
func (a *Account) AutoExpireTTL() time.Duration {
	a.mu.RLock()
	defer a.mu.RUnlock()
	return a.maxaettl
}
1171490
func New(
	ctx context.Context,
	limit Limit,
	burst int,
	options ...interface{},
) (limiter *BucketRateLimiter) {
	ctx, cancel := context.WithCancel(ctx)
	cleanTimeout := time.Minute
	tickerInterval := time.Minute

	for _, option := range options {
		switch opt := option.(type) {
		case OptionCleanTimeout:
			cleanTimeout = time.Duration(opt)
		case OptionCleanTicker:
			tickerInterval = time.Duration(opt)
		}
	}

	egCleaner, _ := errgroup.WithContext(ctx)
	limiter = &BucketRateLimiter{
		ctx:            ctx,
		cancel:         cancel,
		limit:          limit,
		burst:          burst,
		cleanTimeout:   cleanTimeout,
		tickerInterval: tickerInterval,

		buckets:   map[string]*limiterWrap{},
		egCleaner: egCleaner,
		mutex:     sync.Mutex{},
	}
	egCleaner.Go(limiter.cleanerLoop)
	return
}
1245602
func (e *Engine) deleteBucketRangeLocked(orgID, bucketID platform.ID, min, max int64) error {
	// TODO(edd): we need to clean up how we're encoding the prefix so that we
	// don't have to remember to get it right everywhere we need to touch TSM data.
	encoded := tsdb.EncodeName(orgID, bucketID)
	name := models.EscapeMeasurement(encoded[:])

	return e.engine.DeleteBucketRange(name, min, max)
}
784423
func NewBucketService() *BucketService {
	return &BucketService{
		OpenFn:           func() error { return nil },
		CloseFn:          func() error { return nil },
		WithLoggerFn:     func(l *zap.Logger) {},
		FindBucketByIDFn: func(context.Context, platform.ID) (*platform.Bucket, error) { return nil, nil },
		FindBucketFn:     func(context.Context, platform.BucketFilter) (*platform.Bucket, error) { return nil, nil },
		FindBucketsFn: func(context.Context, platform.BucketFilter, ...platform.FindOptions) ([]*platform.Bucket, int, error) {
			return nil, 0, nil
		},
		CreateBucketFn: func(context.Context, *platform.Bucket) error { return nil },
		UpdateBucketFn: func(context.Context, platform.ID, platform.BucketUpdate) (*platform.Bucket, error) { return nil, nil },
		DeleteBucketFn: func(context.Context, platform.ID) error { return nil },
	}
}
593311
func (r *RateLimiter) LockBucket(bucketID string) *Bucket {
	return r.LockBucketObject(r.GetBucket(bucketID))
}
1123698
func (a *AddrManager) expireNew(bucket int) {
	// First see if there are any entries that are so bad we can just throw
	// them away. otherwise we throw away the oldest entry in the cache.
	// Bitcoind here chooses four random and just throws the oldest of
	// those away, but we keep track of oldest in the initial traversal and
	// use that information instead.
	var oldest *KnownAddress
	for k, v := range a.addrNew[bucket] {
		if v.isBad() {
			log.Tracef("expiring bad address %v", k)
			delete(a.addrNew[bucket], k)
			v.refs--
			if v.refs == 0 {
				a.nNew--
				delete(a.addrIndex, k)
			}
			continue
		}
		if oldest == nil {
			oldest = v
		} else if !v.na.Timestamp.After(oldest.na.Timestamp) {
			oldest = v
		}
	}

	if oldest != nil {
		key := NetAddressKey(oldest.na)
		log.Tracef("expiring oldest address %v", key)

		delete(a.addrNew[bucket], key)
		oldest.refs--
		if oldest.refs == 0 {
			a.nNew--
			delete(a.addrIndex, key)
		}
	}
}
628062
func (l *Limiter) LimitReached(key string) bool {
	ttl := l.GetTokenBucketExpirationTTL()

	if ttl <= 0 {
		ttl = l.generalExpirableOptions.DefaultExpirationTTL
	}

	return l.limitReachedWithTokenBucketTTL(key, ttl)
}