@@ -11,8 +11,8 @@ import (
11
11
12
12
var ErrRateLimited = errors .New ("rate limit exceeded" )
13
13
14
- const RlnLimiterCapacity = 100
15
- const RlnLimiterRefillInterval = 10 * time .Minute
14
+ const DefaultRlnLimiterCapacity = 600
15
+ const DefaultRlnLimiterRefillInterval = 10 * time .Minute
16
16
17
17
// RlnRateLimiter is used to rate limit the outgoing messages,
18
18
// The capacity and refillInterval comes from RLN contract configuration.
@@ -22,15 +22,23 @@ type RlnRateLimiter struct {
22
22
tokens int
23
23
refillInterval time.Duration
24
24
lastRefill time.Time
25
+ updateCh chan RlnRateLimitState
26
+ }
27
+
28
+ // RlnRateLimitState includes the information that need to be persisted in database.
29
+ type RlnRateLimitState struct {
30
+ RemainingTokens int
31
+ LastRefill time.Time
25
32
}
26
33
27
34
// 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 , state RlnRateLimitState , updateCh chan RlnRateLimitState ) * RlnRateLimiter {
29
36
return & RlnRateLimiter {
30
37
capacity : capacity ,
31
- tokens : capacity , // Start with a full bucket
38
+ tokens : state . RemainingTokens ,
32
39
refillInterval : refillInterval ,
33
- lastRefill : time .Now (),
40
+ lastRefill : state .LastRefill ,
41
+ updateCh : updateCh ,
34
42
}
35
43
}
36
44
@@ -42,19 +50,26 @@ func (rl *RlnRateLimiter) Allow() bool {
42
50
// Refill tokens if the refill interval has passed
43
51
now := time .Now ()
44
52
if now .Sub (rl .lastRefill ) >= rl .refillInterval {
45
- rl .tokens = rl .capacity // Refill the bucket
53
+ rl .tokens = rl .capacity
46
54
rl .lastRefill = now
55
+ rl .sendUpdate ()
47
56
}
48
57
49
58
// Check if there are tokens available
50
59
if rl .tokens > 0 {
51
60
rl .tokens --
61
+ rl .sendUpdate ()
52
62
return true
53
63
}
54
64
55
65
return false
56
66
}
57
67
68
+ // sendUpdate sends the latest token state to the update channel.
69
+ func (rl * RlnRateLimiter ) sendUpdate () {
70
+ rl .updateCh <- RlnRateLimitState {RemainingTokens : rl .tokens , LastRefill : rl .lastRefill }
71
+ }
72
+
58
73
func (rl * RlnRateLimiter ) Check (ctx context.Context , logger * zap.Logger ) error {
59
74
if rl .Allow () {
60
75
return nil
0 commit comments