2 Star 1 Fork 1

mosache/YFrame

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
silde_window.go 1.19 KB
一键复制 编辑 原始数据 按行查看 历史
ヤ沒脩袮兲︶ 提交于 2023-09-14 18:26 . temp
package ratelimit
import (
"container/list"
"context"
"gitee.com/mosache/YFrame/micro/ratelimit/internal/errs"
"google.golang.org/grpc"
"sync"
"time"
)
type SlideWindowLimiter struct {
cnt int64
interval int64
rate int
queue *list.List
mutex sync.Mutex
}
func NewSlideWindowLimiter(interval time.Duration, rate int) *SlideWindowLimiter {
return &SlideWindowLimiter{
interval: interval.Nanoseconds(),
rate: rate,
queue: list.New(),
}
}
func (s *SlideWindowLimiter) Build() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
s.mutex.Lock()
if s.queue.Len() < s.rate {
resp, err = handler(ctx, req)
s.queue.PushBack(time.Now().UnixNano())
s.mutex.Unlock()
return
}
now := time.Now().UnixNano()
boundary := now - s.interval
ts := s.queue.Front()
for ts != nil && ts.Value.(int64) < boundary {
s.queue.Remove(ts)
ts = s.queue.Front()
}
length := s.queue.Len()
s.mutex.Unlock()
if length >= s.rate {
err = errs.ErrLimiterOverCapacity
return
}
resp, err = handler(ctx, req)
s.queue.PushBack(now)
return
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/mosache/YFrame.git
git@gitee.com:mosache/YFrame.git
mosache
YFrame
YFrame
v0.1.80

搜索帮助