Skip to content

Add retries to Codespaces API client#5064

Merged
mislav merged 4 commits intotrunkfrom
marwan/csretry
Jan 25, 2022
Merged

Add retries to Codespaces API client#5064
mislav merged 4 commits intotrunkfrom
marwan/csretry

Conversation

@marwan-at-work
Copy link
Contributor

@marwan-at-work marwan-at-work commented Jan 19, 2022

This PR adds custom retries to a couple of our Codespaces API calls that may return a 502. Since we only need two calls to be retried for now, I did not introduce a new library that implements retries on the *http.Client but instead just write a small 10 line function.

If more and more API calls need to be retried, then we can certainly add a more generic solution.

Closes internal issue codespaces#5474

@marwan-at-work marwan-at-work requested a review from a team as a code owner January 19, 2022 03:00
@cliAutomation cliAutomation added the external pull request originating outside of the CLI core team label Jan 19, 2022
Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

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

Thank you! This looks like a good start, but I'm concerned about having to change existing methods in order to shoehorn the retry mechanism in. Couldn't it be done as a transparent feature of the API client?


a.setHeaders(req)
resp, err := a.do(ctx, req, "/user/codespaces/*")
resp, err := a.withRetry(func() (*http.Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Couldn't we avoid making any changes to methods like GetCodespace or StartCodespace and implement retries transparently within a.do()? That way the retry mechanism could just kick in for any request that we consider idempotent (typically, GET requests or POST to the start endpoint).

Copy link
Contributor Author

@marwan-at-work marwan-at-work Jan 21, 2022

Choose a reason for hiding this comment

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

@mislav the problem with a.do() is two fold:

  1. Makes it harder to control which methods we want to retry.
  2. More importantly, if the server ever returns redirects, a.do() does not recreate the request therefore net/http will not be able to send the request body again in the case of POST requests. FYI: the net/http library does resend the body in the case of *bytes.Buffer and *bytes/strings.Reader, but that cannot be guaranteed that a caller won't use another underlying io.Reader where the server sends a redirect response.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mislav friendly ping 👋🏼

Copy link
Contributor

Choose a reason for hiding this comment

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

Great point about the difficulties of retrying requests that have a body.

@Liquitity

This comment was marked as spam.


a.setHeaders(req)
resp, err := a.do(ctx, req, "/user/codespaces/*")
resp, err := a.withRetry(func() (*http.Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Great point about the difficulties of retrying requests that have a body.

@mislav mislav merged commit fac2575 into trunk Jan 25, 2022
@mislav mislav deleted the marwan/csretry branch January 25, 2022 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external pull request originating outside of the CLI core team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants