douzhengnao8265 2016-01-07 09:53
浏览 49
已采纳

无法了解此速率限制器的工作原理

I've been trying to make a rate limiter for my application and came across this code. After reading it I still have some trouble understanding what it does exactly.

My current understanding:

1) SetSmallRateLimit and SetLongRateLimit are called to initialize the channels and starts running the handlers in a goroutine.

2) When requestAndUnmarshal is called, checkRateLimiter sends a signal to the queue channel.

What I don't understand:

1) RateLimitHandler sleeps the duration of time.After(pertime) and afterwards clears the queue channel. Not sure what triggerWatcher and returnChan are doing.

2) checkTimeTrigger - Don't understand what this function is doing or its purpose.

var (
    smallRateChan   rateChan
    longRateChan    rateChan
)

type rateChan struct {
    RateQueue   chan bool
    TriggerChan chan bool
}

//10 requests every 10 seconds
func SetSmallRateLimit(numrequests int, pertime time.Duration) {
    smallRateChan = rateChan{
        RateQueue:   make(chan bool, numrequests),
        TriggerChan: make(chan bool),
    }
    go rateLimitHandler(smallRateChan, pertime)
}

//500 requests every 10 minutes
func SetLongRateLimit(numrequests int, pertime time.Duration) {
    longRateChan = rateChan{
        RateQueue:   make(chan bool, numrequests),
        TriggerChan: make(chan bool),
    }
    go rateLimitHandler(longRateChan, pertime)
}

func rateLimitHandler(RateChan rateChan, pertime time.Duration) {
    returnChan := make(chan bool)
    go timeTriggerWatcher(RateChan.TriggerChan, returnChan)
    for {
        <-returnChan
        <-time.After(pertime)
        go timeTriggerWatcher(RateChan.TriggerChan, returnChan)
        length := len(RateChan.RateQueue)
        for i := 0; i < length; i++ {
            <-RateChan.RateQueue
        }
    }
}

func timeTriggerWatcher(timeTrigger chan bool, returnChan chan bool) {
    timeTrigger <- true
    returnChan <- true
}

func requestAndUnmarshal(requestURL string, v interface{}) (err error) {
    checkRateLimiter(smallRateChan)
    checkRateLimiter(longRateChan)
    resp, err := http.Get(requestURL)
    defer resp.Body.Close()
    if err != nil {
        return
    }
    checkTimeTrigger(smallRateChan)
    checkTimeTrigger(longRateChan)
    if resp.StatusCode != http.StatusOK {
        return RiotError{StatusCode: resp.StatusCode}
    }

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return
    }

    err = json.Unmarshal(body, v)
    if err != nil {
        return
    }
    return
}

func checkRateLimiter(RateChan rateChan) {
    if RateChan.RateQueue != nil && RateChan.TriggerChan != nil {
        RateChan.RateQueue <- true
    }
}

func checkTimeTrigger(RateChan rateChan) {
    if RateChan.RateQueue != nil && RateChan.TriggerChan != nil {
        select {
        case <-RateChan.TriggerChan:
        default:
        }
    }
}
  • 写回答

1条回答 默认 最新

  • donpvtzuux37724 2016-01-07 10:46
    关注

    I don't think you should use this code to learn anything useful. I'm not sure but it seems to try to limit the request rate but it's wrong. It allows to make certain amount of request and then wait for a time interval. After the time interval it allows you to make requests again. All of that is done in a very sophisticated way.

    But it can lead to very strange scenarios. Let's say you make 1req/h and your limit is 500req/20sec. Then this code would cause you to wait 20sec after 500 hours and allow to make requests again.

    checkTimeTrigger removes a message from RateChan.TriggerChan if it has any and does nothing if it has not and returns immediately.

    This code isn't obviously DRY. Better use https://godoc.org/golang.org/x/time/rate is you want to limit your request rate.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 我这模型写的不对吗?为什么lingo解出来的下面影子价格这一溜少一个变量
  • ¥50 树莓派安卓APK系统签名
  • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波