git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 3/3] http: automatically retry some requests

From
Sean McAllister <smcallis@google.com>
Date
Oct 14, 2020, 19:09 UTC
Message-ID
<CAM4o00eCKP1+f=xBw4LJfNqrstEnutAe9StxknW9qLMtPBdhKQ@mail.gmail.com>
In-Reply-To
<20201013211453.GB3678071@coredump.intra.peff.net>
On Tue, Oct 13, 2020 at 3:14 PM Jeff King <peff@peff.net> wrote:
Show 16 quoted lines
>
> On Tue, Oct 13, 2020 at 01:17:29PM -0600, Sean McAllister wrote:
>
> > Exiting immediately becomes irksome when pulling large multi-repo code
> > bases such as Android or Chromium, as often the entire fetch operation
> > has to be restarted from the beginning due to an error in one repo. If
> > we can reduce how often that occurs, then it's a big win.
>
> I had hoped that libcurl might have some retry mechanisms, since the
> curl command-line tool has several --retry-* options. But it looks like
> that is all only at the tool level, and the library code doesn't know
> anything about it. So we are stuck driving the process ourselves.
>
> I do think you could be leveraging CURLINFO_RETRY_AFTER rather than
> implementing your own header parsing, though.
>

Ah I didn't know about CURLINFO_RETRY_AFTER, I'll look at that and use it if I can.

Show 12 quoted lines
> >  static int http_request(const char *url,
> >                       void *result, int target,
> >                       const struct http_get_options *options)
> >  {
>
> It looks like you trigger retries only from this function. But this
> doesn't cover all http requests that Git makes. That might be sufficient
> for your purposes (I think it would catch all of the initial contact),
> but it might not (it probably doesn't cover subsequent POSTs for fetch
> negotiation nor pack push; likewise I'm not sure if it covers much of
> anything after v2 stateless-connect is established).
>
You're right that I only trigger from this function.  I've since removed them
in response to feedback on having too many tests, but I originally tested this
with:
  t5539-fetch-http-shallow.sh
  t5540-http-push-webdav.sh
  t5541-http-push-smart.sh
  t5550-http-fetch-dumb.sh
  t5551-http-fetch-smart.sh
  t5601-clone.sh

I'd have to look at the packet logs to see exactly what each of those protocols is doing, but it seemed to cover _most_ of what they were doing.

Definitely open to adding retries in other places though.
Show 42 quoted lines
> >       struct active_request_slot *slot;
> >       struct slot_results results;
> > -     struct curl_slist *headers = http_copy_default_headers();
> > +     struct curl_slist *headers;
>
> So here we stop copying the headers at the top of the function...
>
> > [...]
> > +retry:
> > [...]
> > +     headers = http_copy_default_headers();
> >       if (accept_language)
> >               headers = curl_slist_append(headers, accept_language);
>
> And instead set them up totally here. Which make some sense, because we
> wouldn't want to append accept_language over and over. But who frees the
> old ones? There is a call to curl_slist_free_all(headers) later in the
> function, but it's after your "goto retry". So I think each retry would
> leak another copy of the list.
>
> The ideal thing would probably be to create the header list once, and
> then use it for each retry. That would require reordering some of the
> setup. If that's too much, then it would be OK to just create a new list
> from scratch on each call. Though in the latter case I suspect it may be
> simpler to wrap the whole function, like:
>
>   static int http_request(...)
>   {
>         int try;
>         int result;
>         for (try = 0; try < max_retries; i++) {
>                 result = http_request_try(...);
>                 if (...result is not retryable...)
>                         break;
>         }
>         return result;
>   }
>
> and then we'd know that the single-try function just needs to be
> self-contained, without worrying about gotos jumping around in it.
>
> -Peff
I like this idea, I've refactored it to do just this.
Previous: Jeff KingNext: Sean McAllister
Message 16 of 30 in “remote-curl: add testing for intelligent retry for HTTP”
  1. 1/3 remote-curl: add testing for intelligent retry for HTTPSean McAllister, Oct 13, 2020
  2. 2/3 replace CURLOPT_FILE With CURLOPT_WRITEDATASean McAllister, Oct 13, 2020
  3. Junio C HamanoOct 13, 2020
  4. Jeff KingOct 13, 2020
  5. Daniel StenbergOct 13, 2020
  6. Jeff KingOct 14, 2020
  7. Sean McAllisterOct 14, 2020
  8. Sean McAllisterOct 14, 2020
  9. 3/3 http: automatically retry some requestsSean McAllister, Oct 13, 2020
  10. Junio C HamanoOct 13, 2020
  11. Sean McAllisterOct 14, 2020
  12. Junio C HamanoOct 14, 2020
  13. Jeff KingOct 13, 2020
  14. brian m. carlsonOct 13, 2020
  15. Jeff KingOct 14, 2020
  16. Sean McAllisterOct 14, 2020
  17. Sean McAllisterOct 14, 2020
  18. Jeff KingOct 14, 2020
  19. Sean McAllisterOct 14, 2020
  20. Jonathan NiederOct 15, 2020
  21. Jeff KingOct 15, 2020
  22. Junio C HamanoOct 15, 2020
  23. Jeff KingOct 14, 2020
  24. Sean McAllisterOct 14, 2020
  25. Jeff KingOct 15, 2020
  26. Sean McAllisterOct 15, 2020
  27. Junio C HamanoOct 13, 2020
  28. Sean McAllisterOct 14, 2020
  29. Junio C HamanoOct 14, 2020
  30. Sean McAllisterOct 14, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.