func_limiter.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package rate
  2. import (
  3. "f1-game/internal/code"
  4. )
  5. type (
  6. FuncLimiter struct {
  7. entry // 全局的默认设置
  8. funcEntries map[string]*entry // key: funcName,value: entry
  9. }
  10. entry struct {
  11. interval int64 // 访问时间间隔(ms)
  12. visitLimit int32 // interval时间内最大访问次数
  13. visitNum int32 // 已访问次数
  14. errCode int32 // 返回错误码
  15. deadline int64 // 截止时间(ms)
  16. }
  17. )
  18. func NewFuncLimiter(defaultInterval int64, defaultVisitLimit int32, defaultCode int32) FuncLimiter {
  19. return FuncLimiter{
  20. entry: newEntry(defaultInterval, defaultVisitLimit, defaultCode),
  21. funcEntries: map[string]*entry{},
  22. }
  23. }
  24. func newEntry(interval int64, visitLimit int32, errCode int32) entry {
  25. return entry{
  26. interval: interval,
  27. visitLimit: visitLimit,
  28. visitNum: 0,
  29. errCode: errCode,
  30. deadline: 0,
  31. }
  32. }
  33. func (p *FuncLimiter) Add(funcName string, interval int64, visitLimit int32, errCode int32) {
  34. entry := newEntry(interval, visitLimit, errCode)
  35. p.funcEntries[funcName] = &entry
  36. }
  37. func (p *FuncLimiter) Check(now int64, funcName string) int32 {
  38. if entry, found := p.funcEntries[funcName]; found {
  39. return entry.check(now)
  40. }
  41. return p.check(now)
  42. }
  43. func (p *entry) check(now int64) int32 {
  44. if p.deadline >= now {
  45. p.visitNum++
  46. if p.visitNum >= p.visitLimit {
  47. return p.errCode
  48. }
  49. return code.OK
  50. }
  51. p.deadline = now + p.interval
  52. p.visitNum = 0
  53. return code.OK
  54. }