- Notifications
You must be signed in to change notification settings - Fork673
Fix missing "Retry-After" header and fix integration tests#678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
When requests are throttled (HTTP response code 429), python-gitlabassumed that 'Retry-After' existed in the response headers. This isnot always the case and so the request fails due to a KeyError. Thechange in this commit adds a rudimentary exponential backoff to the'http_request' method, which defaults to 10 retries but can be setto -1 to retry without bound.
The integration tests failed because a test called 'decode()' on astring-type variable - the GitLabException class handles byte-to-stringconversion already in its __init__. This commit removes the call to'decode()' in the test.```Traceback (most recent call last): File "./tools/python_test_v4.py", line 801, in <module> assert 'Retry later' in error_message.decode()AttributeError: 'str' object has no attribute 'decode'```
max-wittig commentedJan 9, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Thanks for this contribution! Looks pretty good. Any way to easily test this? (e.g. against a public GitLab instance without |
srikanthchelluri commentedJan 10, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@max-wittig Hm, this is a bit difficult to test. But here's how I validated the code path - let me know what you think.
whileTrue:# result = self.session.send(prepped, timeout=timeout, **settings)result=requests.get('https://httpstat.us/429')self._check_redirects(result)if200<=result.status_code<300:returnresultif429==result.status_codeandobey_rate_limit:ifmax_retries==-1orcur_retries<max_retries:wait_time=2**cur_retries*0.1if"Retry-AfterXYZ"inresult.headers:wait_time=int(result.headers["Retry-After"])cur_retries+=1print('DEBUG: backing off',str(wait_time))time.sleep(wait_time)continue Note thathttps://httpstat.us returns a response with the
fromgetpassimportgetpassimportgitlabprivate_token=getpass('GitLab API Token: ')gl=gitlab.Gitlab('https://gitlab.com/',private_token=private_token)project=gl.projects.get(<some-project-id-we-own>)project.members.list(all=True)
Thoughts/feedback on this approach? Didn't try spinning up and configuring a GitLab instance without the header since we don't really need it to test the code path. |
@srikanthchelluri Works as expected. Many thanks for the contribution 👍 Just a hint for future contributions: It's best practice to use a separate branch in your fork. Makes it easier for us to checkout the changes and easier for you to maintain your next contribution. Otherwise your master in your fork is polluted by another commit etc. |
@max-wittig This was a separate branch, no? I forked the repo into my org ( Thanks for the review and merge 👍 |
max-wittig commentedJan 13, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
ah really. Okay weird. Nevermind. Maybe I miss-typed something and didn't see it. Not sure 😄 |
Uh oh!
There was an error while loading.Please reload this page.
This PR does two things: a) implements an exponential backoff in the case that we are throttled and "Retry-After" isn't in the response header (this currently causes a
KeyError
), b) fix an integration test because we were decoding something that was already a string.Closes#632.