atuleu / go-lol

Golang Domain, REST API binding and utilities for Riot Games League Of Legends
GNU General Public License v3.0
6 stars 2 forks source link

rate limiter #3

Open yawhide opened 8 years ago

yawhide commented 8 years ago

Hello,

I am confused how your rate limiter works.

So you have in your code

g:      NewRateLimitedRESTGetter(10, 10*time.Second),

in api_endpoint.go

My production key can do 90000 requests every 10 minutes 1500 requests every 10 seconds.

How do I change the rate limiter to use the above contraints instead of what is hard coded in the code?

would I change it to g: NewRateLimitedRESTGetter(1500, 10*time.Second),

atuleu commented 8 years ago

Hi,

I think I made this settings not part of the public interface for a good reason (sorry memory losses).

Internally, the rate limiting is implementing using a kind of semaphore (boolean channel with buffer N). Before each request we acquire a ressource on a semaphore (pushing a true on the channel), and after the request the rate limitter span a go routine that will release the semaphore (reading whatever once from the channel), after a delay of the window.

So basically, it supports only one rate, and spawn a go routine for each request. Its fine for a developper key, and the tool I wrote (a small OS X replay recorder and watcher written in GO, because I was not happy with the existing solutions until now). That would poll my games every minutes and then record them.

For production, this implementation may not be suited at all, if you are hitting the upper bound thats 90000 go routine, and from this stack overflow post, you may expect a memory usage of more than 360 Mb and a negligible computaion overhead of 135ms of computation time over 10 minute for spawning those go routines.

So for an immediate solution, I suggest you to vendor my repo and change those constants directly in your local directory, and cross your finger that your app does not consume too much resources. I have some ideas for an implementation that would consume less ressources, but it will need some development time ( It would require several channels and proper testing).

yawhide commented 8 years ago

Thanks for the tip to vendor your lib! I shall make those changes.

Yeah I am running my app on a 500mb (RAM) machine so I may have to upgrade...but that is a good thing (as ppl will be using my app!)

On Mon, May 9, 2016, 4:09 AM Alexandre Tuleu notifications@github.com wrote:

Hi,

I think I made this settings not part of the public interface for a good reason (sorry memory losses).

Internally, the rate limiting is implementing using a kind of semaphore (boolean channel with buffer N). Before each request we acquire a ressource on a semaphore (pushing a true on the channel), and after the request the rate limitter span a go routine that will release the semaphore (reading whatever once from the channel), after a delay of the window.

So basically, it supports only one rate, and spawn a go routine for each request. Its fine for a developper key, and the tool I wrote (a small OS X replay recorder and watcher written in GO, because I was not happy with the existing solutions until now). That would poll my games every minutes and then record them.

For production, this implementation may not be suited at all, if you are hitting the upper bound thats 90000 go routine, and from this stack overflow post http://stackoverflow.com/questions/8509152/max-number-of-goroutines, you may expect a memory usage of more than 360 Mb and a negligible computaion overhead of 135ms of computation time over 10 minute for spawning those go routines.

So for an immediate solution, I suggest you to vendor https://golang.org/cmd/go/#hdr-Vendor_Directories my repo and change those constants directly in your local directory, and cross your finger that your app does not consume too much resources. I have some ideas for an implementation that would consume less ressources, but it will need some development time ( It would require several channels and proper testing).

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/atuleu/go-lol/issues/3#issuecomment-217801517

atuleu commented 8 years ago

Did not know about that when I made this lib.

It would be easy to refactor everything using this package, I may try to re-implement this in the near future, and hopefully it would not consume so much resources.

yawhide commented 8 years ago

i didn't either, that seems like exactly what we want

yawhide commented 8 years ago

the problem with that library (x/time/rate) is that we dont have a good way of saying "max 500 calls in 600 seconds AND 10 calls in 10 seconds"

it looks like Limit only does /s calls.

I assume the burst size would just be the same as the limit? eg. NewLimiter(1, 1) (for dev keys) or NewLimiter(150, 150) (for prod keys)

also I was looking into how to do it and I dont get how to use that x/context library at all haha