Closed jlucktay closed 11 months ago
Hi @jlucktay , let me have a think about this. There might be two possible ways to do this.
Just a question, do you need to return an error on the first item when you list?
Hi @jlucktay , let me have a think about this. There might be two possible ways to do this.
Just a question, do you need to return an error on the first item when you list?
I think the first github.Repositories.ListByOrg
call should go through OK and return a page of repos, then the second call should give the error of maxing out the rate limit, then the third call should go through OK and return a second (different) page of repos.
I hope that makes sense and that I've understood your question correctly.
Thanks for taking a look! π
The issue seems that this would fundamentally change the underlying behaviour of the mock server as it would have to not just respond a single time with a rate limit (probably a 429), it would have to do that disregards of the mocks you set.
I think the best option is to implement a rate limit in the server level. So there would be no change in the mocks you create. But the server would keep track of the rate of requests.
Also, a rate limiting response might no be treated as an error by github-go
. I would have to double check that.
Actually, Github appears to respond with a 403 :thinking: .
I think the best option is to implement a rate limit in the server level. So there would be no change in the mocks you create. But the server would keep track of the rate of requests.
So, do you think this would require some changes around NewMockedHTTPClient
in src/mock/server.go
?
Maybe some way to add some rate limit middleware onto the Gorilla router there?
@jlucktay exactly.
Gorilla allows global middlewares with .Use()
. See: https://github.com/gorilla/mux#middleware
What I have in mind is to, in order to keep backwards compatibility, there could be a new option type that you could pass a middlware definition that would hijack requests to specific endpoints and throttle them.
Gorilla allows global middlewares with
.Use()
. See: https://github.com/gorilla/mux#middleware
Yes π I've built around this one before.
What I have in mind is to, in order to keep backwards compatibility, there could be a new option type that you could pass a middlware definition that would hijack requests to specific endpoints and throttle them.
I was hacking around with some ideas already. See what you think of this kind of structure:
func WithRateLimit(window time.Duration, rate int) MockBackendOption {
// ... create a rate limiter here, using the 'window' and 'rate' arguments
rateLimitMiddleware := func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// ... check the rate limit
if ok {
next.ServeHTTP(w, r)
} else {
// ... write the GitHub rate limit error back to the ResponseWriter somehow
}
})
}
return func(router *mux.Router) {
router.Use(rateLimitMiddleware)
}
}
This layout would not discriminate between endpoints; it would be a blanket limiter.
edit: I think https://pkg.go.dev/golang.org/x/time/rate#Limiter.Allow would be a good fit to use for this.
Hi there, and thank you for this library, it's super helpful!
I'm trying to test a scenario where my GitHub client hits the rate limit whilst paginating through some responses, listing a considerable number of repositories from a large organisation. However, I can't seem to find the right sequence of
mock.MockBackendOption
to set things off.Abbreviated snippet of my code for listing repos, paginating, and handling rate limit errors
In my test for this function, this is how I have structured my mocked
*http.Client
:"mock.NewMockedHTTPClient" with several "mock.MockBackendOption" arguments
I think it's because the
if resp.NextPage == 0
condition always evaluates true from that first mocked page, which is how thego-github
example for pagination goes. Is there any way to have that first mocked page give a non-zero value forNextPage
? Would I be best served writing up a custom handler withmock.WithRequestMatchHandler
wrapped aroundhttp.HandlerFunc
or is there a more direct way to cover off this test scenario?Again, thanks very much! π