Skip to content

Commit 8a33247

Browse files
authored
Merge pull request #6 from augustus281/DEV
[algo]: sliding window log
2 parents 36321b5 + e80fbec commit 8a33247

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ The package can be installed as a Go module.
66

77
```
88
go get github.com/augustus281/ratelimiter
9-
```
9+
```

sliding_window_log.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package ratelimiter
2+
3+
import (
4+
"sync"
5+
"time"
6+
)
7+
8+
type SlidingWindowLog struct {
9+
window_size time.Duration
10+
maxRequests int
11+
requestLog []time.Time
12+
mu sync.Mutex
13+
}
14+
15+
func NewSlidingWindowLog(window_size time.Duration, max_requests int) *SlidingWindowLog {
16+
return &SlidingWindowLog{
17+
window_size: window_size,
18+
maxRequests: max_requests,
19+
requestLog: make([]time.Time, 0),
20+
}
21+
}
22+
23+
func (swl *SlidingWindowLog) AllowRequest() bool {
24+
swl.mu.Lock()
25+
defer swl.mu.Unlock()
26+
27+
now := time.Now()
28+
// Remove timestamps that are outside the current window
29+
for len(swl.requestLog) > 0 && now.Sub(swl.requestLog[0]) >= swl.window_size {
30+
swl.requestLog = swl.requestLog[1:]
31+
}
32+
33+
// Check if we're still within the limit
34+
if len(swl.requestLog) < swl.maxRequests {
35+
swl.requestLog = append(swl.requestLog, now)
36+
return true
37+
}
38+
39+
return false
40+
}

sliding_window_log_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package ratelimiter
2+
3+
import (
4+
"testing"
5+
"time"
6+
)
7+
8+
func TestSlidingWindowLog(t *testing.T) {
9+
limiter := NewSlidingWindowLog(1*time.Second, 3)
10+
11+
for i := 0; i < 3; i++ {
12+
if !limiter.AllowRequest() {
13+
t.Errorf("Expected request %d to be allowed, but it was denied", i+1)
14+
}
15+
}
16+
17+
if limiter.AllowRequest() {
18+
t.Errorf("Expected the 4th request to be denied, but it was allowed")
19+
}
20+
21+
time.Sleep(1 * time.Second)
22+
23+
if !limiter.AllowRequest() {
24+
t.Errorf("Expected the request after the window slide to be allowed, but it was denied")
25+
}
26+
}

0 commit comments

Comments
 (0)