Skip to content

Commit

Permalink
Add SetGlobalRequestLimit and SetChatRequestLimit
Browse files Browse the repository at this point in the history
  • Loading branch information
NicoNex committed May 24, 2024
1 parent f7ce0a0 commit 6636d2e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
2 changes: 1 addition & 1 deletion api.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
type API struct {
token string
base string
client client
client *client
}

// NewAPI returns a new API object.
Expand Down
44 changes: 35 additions & 9 deletions network.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,63 @@ import (
"net/url"
"path/filepath"
"strings"
"sync"
"time"

"golang.org/x/time/rate"
)

type client struct {
*http.Client
cl map[string]*rate.Limiter // chat based limiter
gl *rate.Limiter // global limiter
*sync.RWMutex
cl map[string]*rate.Limiter // chat based limiter
gl *rate.Limiter // global limiter
climiter func() *rate.Limiter
}

var lclient = newClient()

func newClient() client {
return client{
Client: &http.Client{},
cl: make(map[string]*rate.Limiter),
gl: rate.NewLimiter(rate.Every(time.Second/30), 10),
// SetGlobalRequestLimit sets the global frequency of requests to the Telegram API.
func SetGlobalRequestLimit(d time.Duration) {
lclient.Lock()
lclient.gl = rate.NewLimiter(rate.Every(d), 10)
lclient.Unlock()
}

// SetChatRequestLimit sets the per-chat frequency of requests to the Telegram API.
func SetChatRequestLimit(d time.Duration) {
lclient.Lock()
lclient.cl = make(map[string]*rate.Limiter)
lclient.climiter = func() *rate.Limiter {
return rate.NewLimiter(rate.Every(d), 1)
}
lclient.Unlock()
}

func newClient() *client {
return &client{
Client: new(http.Client),
RWMutex: new(sync.RWMutex),
cl: make(map[string]*rate.Limiter),
gl: rate.NewLimiter(rate.Every(time.Second/30), 10),
climiter: func() *rate.Limiter {
return rate.NewLimiter(rate.Every(time.Minute/20), 1)
},
}
}

func (c client) wait(chatID string) error {
var ctx = context.Background()
c.RLock()
defer c.RUnlock()

ctx := context.Background()
// If the chatID is empty, it's a general API call like GetUpdates, GetMe
// and similar, so skip the per-chat request limit wait.
if chatID != "" {
// If no limiter exists for a chat, create one.
l, ok := c.cl[chatID]
if !ok {
l = rate.NewLimiter(rate.Every(time.Minute/20), 1)
l = c.climiter()
c.cl[chatID] = l
}

Expand Down

0 comments on commit 6636d2e

Please sign in to comment.