@@ -11,7 +11,7 @@ import (
1111
1212var ErrRateLimited = errors .New ("rate limit exceeded" )
1313
14- const RlnLimiterCapacity = 100
14+ const RlnLimiterCapacity = 600
1515const RlnLimiterRefillInterval = 10 * time .Minute
1616
1717// RlnRateLimiter is used to rate limit the outgoing messages,
@@ -22,15 +22,23 @@ type RlnRateLimiter struct {
2222 tokens int
2323 refillInterval time.Duration
2424 lastRefill time.Time
25+ updateCh chan BucketUpdate
26+ }
27+
28+ // BucketUpdate includes the information that need to be persisted in database.
29+ type BucketUpdate struct {
30+ RemainingTokens int
31+ LastRefill time.Time
2532}
2633
2734// NewRlnPublishRateLimiter creates a new rate limiter, starts with a full capacity bucket.
28- func NewRlnRateLimiter (capacity int , refillInterval time.Duration ) * RlnRateLimiter {
35+ func NewRlnRateLimiter (capacity int , refillInterval time.Duration , availableTokens int , lastRefill time. Time , updateCh chan BucketUpdate ) * RlnRateLimiter {
2936 return & RlnRateLimiter {
3037 capacity : capacity ,
31- tokens : capacity , // Start with a full bucket
38+ tokens : availableTokens , // Start with a full bucket in the first run, then track the remaining tokens in storage
3239 refillInterval : refillInterval ,
33- lastRefill : time .Now (),
40+ lastRefill : lastRefill ,
41+ updateCh : updateCh ,
3442 }
3543}
3644
@@ -42,19 +50,26 @@ func (rl *RlnRateLimiter) Allow() bool {
4250 // Refill tokens if the refill interval has passed
4351 now := time .Now ()
4452 if now .Sub (rl .lastRefill ) >= rl .refillInterval {
45- rl .tokens = rl .capacity // Refill the bucket
53+ rl .tokens = rl .capacity
4654 rl .lastRefill = now
55+ rl .sendUpdate ()
4756 }
4857
4958 // Check if there are tokens available
5059 if rl .tokens > 0 {
5160 rl .tokens --
61+ rl .sendUpdate ()
5262 return true
5363 }
5464
5565 return false
5666}
5767
68+ // sendUpdate sends the latest token state to the update channel.
69+ func (rl * RlnRateLimiter ) sendUpdate () {
70+ rl .updateCh <- BucketUpdate {RemainingTokens : rl .tokens , LastRefill : rl .lastRefill }
71+ }
72+
5873func (rl * RlnRateLimiter ) Check (ctx context.Context , logger * zap.Logger ) error {
5974 if rl .Allow () {
6075 return nil
0 commit comments