Skip to content

Commit 609e976

Browse files
authored
Merge pull request #126 from slyang08/fix/llm-api-limitation
fix: no rate limiting if llm api calls
2 parents 446eedf + 363c20f commit 609e976

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

cmd/cli/createMsg.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os/exec"
99
"runtime"
1010
"strings"
11+
"time"
1112

1213
"github.com/atotto/clipboard"
1314
"github.com/dfanso/commit-msg/cmd/cli/store"
@@ -18,8 +19,13 @@ import (
1819
"github.com/dfanso/commit-msg/pkg/types"
1920
"github.com/google/shlex"
2021
"github.com/pterm/pterm"
22+
"golang.org/x/time/rate"
2123
)
2224

25+
// Burst once every 5 times per second
26+
// Make the limiter a global variable to better control the rate when it is used.
27+
var apiRateLimiter = rate.NewLimiter(rate.Every(time.Second/5), 5)
28+
2329
// CreateCommitMsg launches the interactive flow for reviewing, regenerating,
2430
// editing, and accepting AI-generated commit messages in the current repo.
2531
// If dryRun is true, it displays the prompt without making an API call.
@@ -340,6 +346,9 @@ func resolveOllamaConfig(apiKey string) (url, model string) {
340346
}
341347

342348
func generateMessage(ctx context.Context, provider llm.Provider, changes string, opts *types.GenerationOptions) (string, error) {
349+
if err := apiRateLimiter.Wait(ctx); err != nil {
350+
return "", err
351+
}
343352
return provider.Generate(ctx, changes, opts)
344353
}
345354

cmd/cli/createMsg_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"sync"
6+
"testing"
7+
8+
"github.com/dfanso/commit-msg/pkg/types"
9+
)
10+
11+
// FakeProvider implements the llm.Provider interface to simulate API responses
12+
type FakeProvider struct{}
13+
14+
func (f FakeProvider) Name() types.LLMProvider { return "fake" }
15+
16+
func (f FakeProvider) Generate(ctx context.Context, changes string, opts *types.GenerationOptions) (string, error) {
17+
return "mock commit message", nil
18+
}
19+
20+
func TestGenerateMessageRateLimiter(t *testing.T) {
21+
ctx := context.Background()
22+
var waitGroup sync.WaitGroup
23+
successCount := 0
24+
var mu sync.Mutex
25+
26+
// Test sending a number of messages in a short period to check the rate limiter
27+
numCalls := 100
28+
waitGroup.Add(numCalls)
29+
for i := 0; i < numCalls; i++ {
30+
go func() {
31+
defer waitGroup.Done()
32+
_, err := generateMessage(ctx, FakeProvider{}, "", nil)
33+
if err != nil {
34+
t.Logf("rate limiter error: %v", err)
35+
return
36+
}
37+
mu.Lock()
38+
successCount++
39+
mu.Unlock()
40+
}()
41+
}
42+
waitGroup.Wait()
43+
44+
t.Logf("Successful calls: %d out of %d", successCount, numCalls)
45+
if successCount != numCalls {
46+
t.Errorf("expected %d successful calls but got %d", numCalls, successCount)
47+
}
48+
}

0 commit comments

Comments
 (0)