I have an API that I am POSTing a small JSON object too.
This runs as an infinite loop, looping over 7 colours (the rainbow) and send these inside the aforementioned JSON object.
The API I am connecting to has a rate limit on it of 40 requests per minute.
I don't want to hit the rate limit and so I have devised a method to avoid this;
- I have a global variable that stores the number of requests I am allowed to make
- I have a function that holds a ticker set to run every 60 seconds and top up the global variable that stores my requests
- I then have a never ending for loop that runs and checks the number of requests that are still allowed to be made, if it is greater than 0 then we make our next request, if is not then we just sleep for a second and try again
It looks a little something like this:
var rateLimit int
func main() {
request := gorequest.New().SetDebug(false)
// Set the initial request bucket to 40
rateLimit = 40
go topUpLimiter()
for {
makeTheLightsBlinkTheRainbow(request)
}
}
func topUpLimiter() {
for range time.Tick(60 * time.Second) {
rateLimit += 40
}
}
func makeTheLightsBlinkTheRainbow(request *gorequest.SuperAgent) {
colours := [7]string{"red", "orange", "yellow", "green", "blue", "purple", "pink"}
for _, colour := range colours {
if rateLimit > 0 {
response, _, _ := request.Post("http://example.com/blink").
Send(fmt.Sprintf(`{"color":"%v"}`, colour)).
End()
rateLimit--
} else {
time.Sleep(1 * time.Second)
}
}
}
This works and I don't ever hit the rate limit, but once I run out of requests, the loop continues to run and will only starts making requests again when the rateLimit
variable is topped up.
I am making an IoT light blink the colours of the rainbow and the result is the colours get out of order once the rateLimit
variable runs out and is then later topped up due to the fact that the for loop just keeps running.
I'd like to pause/block the for loop while I wait for the rateLimit
variable to replenish so that the colours don't get out of order.
How would I implement something like that? From my searches it seems like it may be possible with channels, but I'm not too sure how to do it like that.
This is an example of what ends up happening: https://play.golang.org/p/r6OG4kK9vCP Once it has finished running, you will notice the colours printed out get out of order about halfway through.