Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(http): Support for Retry-After header #25859

Merged
merged 54 commits into from
Dec 14, 2023

Conversation

zharinov
Copy link
Collaborator

@zharinov zharinov commented Nov 19, 2023

Changes

  • Wrap http requests into retry logic which works only for 429 responses with Retry-After header
  • Provide optional configuration with maxRetryAfter option via host rules

Context

Documentation (please check one with an [x])

  • I have updated the documentation, or
  • No documentation update is required

How I've tested my work (please select one)

I have verified these changes via:

  • Code inspection only, or
  • Newly added/modified unit tests, or
  • No unit tests but ran on a real repository, or
  • Both unit tests + ran on a real repository

Copy link
Member

@viceice viceice left a comment

Choose a reason for hiding this comment

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

I think we need to check got retry, it's doing 2 retries by default which shouldn't happen when we get a retry after header.

lib/util/http/retry-after.ts Outdated Show resolved Hide resolved
@zharinov
Copy link
Collaborator Author

Live test

  • lib/test.ts:
import httpServer from 'http';
import { Http } from './util/http';

let countdown = 2;

const server = httpServer
  .createServer(function (req, res) {
    if (countdown === 0) {
      // eslint-disable-next-line no-console
      console.log('Response 200');

      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ msg: 'Hello World' }));

      server.closeAllConnections();
      server.close();
    } else {
      // eslint-disable-next-line no-console
      console.log('Response 429');

      countdown -= 1;
      res.writeHead(429, {
        'Content-Type': 'application/json',
        'retry-after': '5',
      });
      res.end(JSON.stringify({ msg: 'Too Many Requests' }));
    }
  })
  .listen(1337, '127.0.0.1');

const client = new Http('foobar');
client
  .get('http://127.0.0.1:1337/')
  .then((res) => {
    // eslint-disable-next-line no-console
    console.log(res);
    return 0;
  })
  .catch((err) => {
    // eslint-disable-next-line no-console
    console.error(err);
  });
time pnpm ts-node lib/test.ts
Response 429
Response 429
Response 200
{
  statusCode: 200,
  body: '{"msg":"Hello World"}',
  headers: {
    'content-type': 'application/json',
    date: 'Sun, 19 Nov 2023 20:28:53 GMT',
    connection: 'keep-alive',
    'keep-alive': 'timeout=5',
    'transfer-encoding': 'chunked'
  },
  authorization: false
}
pnpm ts-node lib/test.ts  0.84s user 0.13s system 9% cpu 10.762 total

@zharinov zharinov marked this pull request as ready for review November 19, 2023 20:34
@zharinov zharinov requested review from viceice and rarkins November 19, 2023 20:34
Copy link
Collaborator

@rarkins rarkins left a comment

Choose a reason for hiding this comment

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

  1. Should also work for GitHub secondary rate limit, which I think is a 401
  2. Make sure logging is adequate whenever this happens

lib/config/options/index.ts Show resolved Hide resolved
@zharinov zharinov requested review from rarkins and viceice November 20, 2023 23:49
lib/config/options/index.ts Outdated Show resolved Hide resolved
lib/util/http/retry-after.ts Outdated Show resolved Hide resolved
lib/util/http/retry-after.ts Outdated Show resolved Hide resolved
lib/util/http/retry-after.ts Outdated Show resolved Hide resolved
zharinov and others added 2 commits November 21, 2023 11:43
@zharinov zharinov requested a review from rarkins November 21, 2023 15:14
Copy link
Collaborator

@rarkins rarkins left a comment

Choose a reason for hiding this comment

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

Any way to test this in practice?

docs/usage/configuration-options.md Outdated Show resolved Hide resolved
@zharinov
Copy link
Collaborator Author

Any way to test this in practice?

Copy link
Collaborator

@rarkins rarkins left a comment

Choose a reason for hiding this comment

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

Does this work if there are concurrent requests to the same host, e.g. a datasource rate limit and we have multiple requests to the same datasource?

Copy link
Member

@viceice viceice left a comment

Choose a reason for hiding this comment

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

otherwise LGTM

lib/util/http/retry-after.ts Show resolved Hide resolved
@zharinov
Copy link
Collaborator Author

Does this work if there are concurrent requests to the same host, e.g. a datasource rate limit and we have multiple requests to the same datasource?

When the first response is received, any further request will be made after the delay. None of the queueing is done for now, i.e. they will fire simultaneously after the delay.

Copy link
Member

@viceice viceice left a comment

Choose a reason for hiding this comment

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

otherwise LGTM

lib/util/http/retry-after.ts Outdated Show resolved Hide resolved
lib/util/http/retry-after.ts Show resolved Hide resolved
lib/util/http/retry-after.ts Show resolved Hide resolved
@rarkins rarkins requested review from viceice and secustor December 6, 2023 07:47
@rarkins rarkins self-requested a review December 6, 2023 12:23
@viceice
Copy link
Member

viceice commented Dec 13, 2023

@rarkins can we get this done please?

@rarkins
Copy link
Collaborator

rarkins commented Dec 13, 2023

@viceice please check the outstanding conversation to be resolved

@viceice
Copy link
Member

viceice commented Dec 14, 2023

we now retry for any 4xx error that's fine by me

@viceice viceice enabled auto-merge December 14, 2023 07:06
@viceice viceice added this pull request to the merge queue Dec 14, 2023
Merged via the queue into renovatebot:main with commit 3aaa3e5 Dec 14, 2023
38 of 50 checks passed
@viceice viceice deleted the feat/http-retry-after branch December 14, 2023 07:17
@renovate-release
Copy link
Collaborator

🎉 This PR is included in version 37.93.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

hersentino pushed a commit to hiventive/renovate that referenced this pull request Jan 9, 2024
Co-authored-by: Rhys Arkins <[email protected]>
Co-authored-by: HonkingGoose <[email protected]>
Co-authored-by: Michael Kriese <[email protected]>
Co-authored-by: Sebastian Poxhofer <[email protected]>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 14, 2024
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.

Support retry-after headers (e.g. for 429)
6 participants