ISSUE-627: (feature/retry-after-sync) Add handling of Retry-After header for 429 and 503 status codes for sync requests#628
Conversation
|
DAVErrpr is the correct parent class for errors. I think that some sleep-retry-logic should be implemented as well, with a max_sleep defined in the DAVClient object. 3s is probably a good default. So if the retry-after is before the sleep limit, then sleep (async and sync logic for it), otherwise raise the exception. (That makes sense in my head at least, I don't know if you have other ideas) |
|
@tobixen Thank you for your ideas! :) I have added the parameters By default, rate limit handling is disabled. This means that sleeping in case of a rate limit will only occur if the user explicitly sets these parameters in the DAVClient class. I did this to ensure that if any library users decide to update, and they already have their own logic for handling rate limits on their side, there will be no duplication and their existing scripts will not break. Initially, I propose to introduce this logic exclusively for the synchronous class, test its operation in my live environment, and confirm its stability. Subsequently, if the results are positive, we can proceed to adapt and migrate the logic to the asynchronous class. |
|
A small issue with the defaults:
What does For For |
|
The current behavior is as follows:
|
| This parameter has no effect if enable_rfc6764=False. | ||
| rate_limit_handle: boolean, a parameter that determines whether the rate limit response | ||
| should be handled. Default: False. | ||
| rate_limit_default_sleep: integer, the default number of seconds to sleep if the server |
There was a problem hiding this comment.
So if I understand it right, None here will cause it to raise the RateLimitError on 429s without retry-after, this should be explicit in the inline documentation here.
| rate_limit_default_sleep: integer, the default number of seconds to sleep if the server | ||
| response cannot be parsed, or if no retry-after is specified | ||
| and the HTTP response status code is 429. Default: None. | ||
| rate_limit_max_sleep: integer, the maximum number of seconds the script will sleep |
There was a problem hiding this comment.
Here, None means "respect retry-after, no matter if it's some few seconds or some few weeks". Should be explicit in the comments.
|
I'll go sleep now, will merge it tomorrow. |
|
(Disclaimer - text below was written by Claude, the AI) Thank you for this contribution! The feature has been incorporated in commit 722e959 on master (with some fixes applied during code review). The following issues were corrected before merging:
11 unit tests were also added covering the main behaviours (integer and HTTP-date Retry-After parsing, 503 without Retry-After passing through, sleep+retry, default sleep fallback, max-sleep cap, etc.). This pull request was reviewed and the fixes were vibe-coded with the assistance of Claude Code. |
|
Closing — changes incorporated in commit 722e959 on master. |
…9110) Merges and fixes PR #628 by temsocial (#628). New `DAVClient` parameters: - `rate_limit_handle` (bool, default False): when True, automatically sleep and retry on rate-limited responses; when False raise `RateLimitError` immediately so callers can implement their own strategy. - `rate_limit_default_sleep` (Optional[int], default None): fallback sleep in seconds when the server's 429 omits a Retry-After header. None means raise rather than guess a sleep duration. - `rate_limit_max_sleep` (Optional[int], default None): cap on the sleep duration; None means respect the server's value without limit. New `error.RateLimitError(DAVError)` with `retry_after` (raw header string) and `retry_after_seconds` (parsed float) attributes. 11 unit tests added to `TestRateLimiting` in `tests/test_caldav_unit.py`. Co-authored-by: temsocial <temsocial@users.noreply.github.com> Assisted-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Details: #627
Added:
1 - a new class in error.py
2 - new logic for status_code in (429, 503) and "Retry-After" in r_headers