Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Implement a rate limiting stategy #800

Merged
merged 1 commit into from
Mar 23, 2020
Merged

Implement a rate limiting stategy #800

merged 1 commit into from
Mar 23, 2020

Conversation

svanharmelen
Copy link
Member

This adds both a rate limiter in order to try and prevent hitting the
limit all together, and in addition it adds some retry logic.

Fixes #630

Copy link
Contributor

@veverkap veverkap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome!

@svanharmelen
Copy link
Member Author

@veverkap it would be super nice if you could verify this solution?

I have limited access to a GitLab instance and don't actually use GitLab much these days, so I'm going to wait with merging this one until 2 individuals have confirmed that this change doesn't break anything for them and that the rate limiting and retry logic work as expected.

So if you can give the code in this PR a go, that would be very much appreciated!

This adds both a rate limiter in order to try and prevent hitting the
limit all together, and in addition it adds some retry logic.
@veverkap
Copy link
Contributor

Went ahead and tried this locally and couldn't break it.

👍

@svanharmelen
Copy link
Member Author

Thanks for testing it @veverkap! If anyone else can find some time to also test it, then I will merge it right after that... Thanks again!

@totobest
Copy link

Tested with upstream project terraform-gitlab-provider and did not break!

@svanharmelen
Copy link
Member Author

Cool... In that case I am going to merge this one today. Thanks for testing it!

@svanharmelen svanharmelen merged commit 629ba2b into master Mar 23, 2020
@svanharmelen svanharmelen deleted the svh/f-rate-limit branch March 23, 2020 13:11
@mvisonneau
Copy link
Contributor

I reckon it would be nice to be able to configure this behaviour, the currently hard coded solution returns non 2xx responses in ~5 minutes. This might not be ideal for everyone.

mvisonneau added a commit to mvisonneau/gitlab-ci-pipelines-exporter that referenced this pull request Mar 27, 2020
The 0.29.0 version adds some auto-retry capabilities which makes some of our
tests take ~5min 🤦

xanzy/go-gitlab#800 (comment)
@svanharmelen
Copy link
Member Author

Care to share some more details about that comment @mvisonneau? As that would be a bug in my opinion, so wondering what you observed...

@mvisonneau
Copy link
Contributor

This is for instance what I experience in this test : https://github.com/mvisonneau/gitlab-ci-pipelines-exporter/blob/master/cmd/gitlab_test.go#L180

I am not convinced that I always want to be stuck in a retry-loop for 5m if the GitLab API returns me either a 429 or a 5xx 🤔

@svanharmelen
Copy link
Member Author

svanharmelen commented Mar 27, 2020

It should be simple enough to put in a global switch to disable the retry logic. Would that solve your worries?

Hmm... Actually have a better idea to make this configurable using options when creating the client. Let me wipe up a PR (next week probably) and see if we can find a nice solution.

@mvisonneau
Copy link
Contributor

Yeah I really like the idea of having this retry capability as well and thanks for the implementation btw 🙇. I believe that being able to customize the behaviour at the client config level would be great indeed 👍

@svanharmelen
Copy link
Member Author

svanharmelen commented Mar 30, 2020

So... This turned out to be a backwards incompatible change, but considering most (if not all) people only create 1 client in their code it's a super small change to make your code work with this new logic.

The big advantage is that now we introduced client options in this way, we should be pretty future proof and flexible going forward.

The PR (#813) is pretty big, but the things that matter are:

In your code this should be a working solution:

func getMockedGitlabClient() (*http.ServeMux, *httptest.Server, *Client) {
	mux := http.NewServeMux()
	server := httptest.NewServer(mux)

	c := &Client{
		Client:      gitlab.NewClient(&http.Client{}, ""),
		RateLimiter: ratelimit.New(100),
	}
	if err := gitlab.WithBaseURL(server.URL)(c); err != nil {
		panic(err) // Or adapt the helper function to return an error
	}
	if err := gitlab.WithoutRetries()(c); err != nil {
		panic(err) // Or adapt the helper function to return an error
	}

	return mux, server, c
}

Would this be a workable solution for you @mvisonneau?

@mvisonneau
Copy link
Contributor

mvisonneau commented Mar 30, 2020

That would be perfectly fine for me, thanks a lot @svanharmelen! 🙇 🙏

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Does not handle retries or backoff for Gitlab.com API endpoints
4 participants