Skip to content

Commit 7209d94

Browse files
committed
Implement benchmark for Redis backend
1 parent 0665713 commit 7209d94

File tree

3 files changed

+95
-1
lines changed

3 files changed

+95
-1
lines changed

.github/workflows/benchmark.yml

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Bechmark
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
benchmark:
8+
name: Benchmark
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Set up Go
12+
uses: actions/setup-go@v5
13+
with:
14+
go-version: ^1.17
15+
16+
- name: Git clone (master)
17+
uses: actions/checkout@v4
18+
with:
19+
ref: master
20+
21+
- name: Run benchmark (master)
22+
run: go test -bench=. -count=10 -benchmem | tee /tmp/master.txt
23+
24+
- name: Git clone (PR)
25+
uses: actions/checkout@v4
26+
27+
- name: Run benchmark (PR)
28+
run: go test -bench=. -count=10 -benchmem | tee /tmp/pr.txt
29+
30+
- name: Install benchstat
31+
run: go install golang.org/x/perf/cmd/benchstat@latest
32+
33+
- name: Run benchstat
34+
run: cd /tmp && benchstat master.txt pr.txt | tee /tmp/result.txt
35+
36+
- name: Comment on PR with benchmark results
37+
uses: actions/github-script@v6
38+
with:
39+
script: |
40+
const fs = require('fs');
41+
const results = fs.readFileSync('/tmp/result.txt', 'utf8');
42+
const issue_number = context.payload.pull_request.number;
43+
const { owner, repo } = context.repo;
44+
45+
await github.rest.issues.createComment({
46+
owner,
47+
repo,
48+
issue_number,
49+
body: `### Benchmark Results\n\n\`\`\`\n${results}\n\`\`\``
50+
});

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"github.com/go-chi/chi/v5"
2323
"github.com/go-chi/chi/v5/middleware"
2424
"github.com/go-chi/httprate"
25-
httprateredis "github.com/go-chi/httprate-redis"
25+
httprateredis "github.com/go-chi/httprate-redis"
2626
)
2727

2828
func main() {

httprateredis_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package httprateredis_test
33
import (
44
"fmt"
55
"math/rand"
6+
"sync"
67
"testing"
78
"time"
89

@@ -150,3 +151,46 @@ func TestRedisCounter(t *testing.T) {
150151
}
151152
}
152153
}
154+
155+
func BenchmarkLocalCounter(b *testing.B) {
156+
limitCounter, err := httprateredis.NewRedisLimitCounter(&httprateredis.Config{
157+
Host: "localhost",
158+
Port: 6379,
159+
MaxIdle: 500,
160+
MaxActive: 500,
161+
DBIndex: 0,
162+
ClientName: "httprateredis_test",
163+
PrefixKey: fmt.Sprintf("httprate:test:%v", rand.Int31n(100000)), // Unique key for each test
164+
})
165+
if err != nil {
166+
b.Fatalf("redis not available: %v", err)
167+
}
168+
169+
limitCounter.Config(1000, time.Minute)
170+
171+
currentWindow := time.Now().UTC().Truncate(time.Minute)
172+
previousWindow := currentWindow.Add(-time.Minute)
173+
174+
b.ResetTimer()
175+
176+
for i := 0; i < b.N; i++ {
177+
for i := range []int{0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0} {
178+
// Simulate time.
179+
currentWindow.Add(time.Duration(i) * time.Minute)
180+
previousWindow.Add(time.Duration(i) * time.Minute)
181+
182+
wg := sync.WaitGroup{}
183+
wg.Add(1000)
184+
for i := 0; i < 1000; i++ {
185+
// Simulate concurrent requests with different rate-limit keys.
186+
go func(i int) {
187+
defer wg.Done()
188+
189+
_, _, _ = limitCounter.Get(fmt.Sprintf("key:%v", i), currentWindow, previousWindow)
190+
_ = limitCounter.IncrementBy(fmt.Sprintf("key:%v", i), currentWindow, rand.Intn(100))
191+
}(i)
192+
}
193+
wg.Wait()
194+
}
195+
}
196+
}

0 commit comments

Comments
 (0)