-
Notifications
You must be signed in to change notification settings - Fork 10
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
devkit: import retry from ahrefskit #12
Open
glionnet
wants to merge
1
commit into
master
Choose a base branch
from
import_retry
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ | |
lwt_flag | ||
lwt_util | ||
parallel | ||
retry | ||
web)) | ||
)) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
open Prelude | ||
|
||
let log = Log.from "retry" | ||
|
||
(** Clamped random exponential backoff for retry *) | ||
let exp_backoff_pause ?max_delay attempt = | ||
let sleep = Random.int (attempt + 1) in | ||
let pause = 2. ** float sleep -. 1. in | ||
Option.map_default (min pause) pause max_delay | ||
|
||
let wait_pause'' ?(ignore_should_exit = false) poll pause = | ||
log #info "will wait for %s" (Time.duration_str pause); | ||
let need_stamp = Time.now () +. pause in | ||
let rec loop () = | ||
match Time.now () with | ||
| now when now < need_stamp && (ignore_should_exit || Daemon.should_run ()) -> | ||
Nix.sleep (min 2. (need_stamp -. now)); | ||
poll (); | ||
loop () | ||
| _ -> () | ||
in | ||
loop () | ||
|
||
let wait_pause' ?ignore_should_exit = wait_pause'' ?ignore_should_exit id | ||
let wait_pause ?ignore_should_exit master = wait_pause'' ?ignore_should_exit master#poll | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this doesn't belong to shared code.. |
||
|
||
|
||
(* Exponentially increasing sleep pause depending of the number of attempts already made. | ||
Since the loop is not managed by this function, the number of attempts already made must be provided. | ||
*) | ||
let backoff_log ~exn ~name attempt = | ||
function | ||
| None -> log #warn ~exn "%s: aborting after %d max_retries" name attempt | ||
| Some pause -> | ||
log #warn ~exn "%s: will retry in %s (try #%d)" name (Time.duration_str pause) attempt | ||
|
||
let exp_backoff ?(f_retry=id) ~exn ~name ?max_retries ~max_delay attempt = | ||
match attempt, max_retries with | ||
| n, Some max_retries when n > max_retries -> | ||
backoff_log ~exn ~name attempt None; | ||
Lwt.fail exn | ||
| attempt, _ -> | ||
let pause = exp_backoff_pause ~max_delay attempt in | ||
f_retry (); | ||
backoff_log ~exn ~name attempt (Some pause); | ||
let%lwt () = Lwt_unix.sleep pause in | ||
Lwt.return (attempt + 1) | ||
|
||
let backoff_log_result to_string error ~name attempt = | ||
function | ||
| None -> log #warn "%s: aborting after %d max_retries %s" name attempt (to_string error) | ||
| Some pause -> | ||
log #warn "%s: will retry in %s (try #%d) %s" name (Time.duration_str pause) attempt (to_string error) | ||
|
||
let exp_backoff_result ?(f_retry=id) to_string error ~name ?max_retries ~max_delay attempt = | ||
match attempt, max_retries with | ||
| n, Some max_retries when n > max_retries -> | ||
backoff_log_result to_string error ~name attempt None; | ||
Lwt.return_error error | ||
| attempt, _ -> | ||
let pause = exp_backoff_pause ~max_delay attempt in | ||
f_retry (); | ||
backoff_log_result to_string error ~name attempt (Some pause); | ||
let%lwt () = Lwt_unix.sleep pause in | ||
Lwt.return_ok (attempt + 1) | ||
|
||
let with_exp_backoff ~name ?f_retry ?max_retries ~max_delay f = | ||
let rec loop f attempt = | ||
try%lwt | ||
f () | ||
with | ||
| Daemon.ShouldExit | Lwt.Canceled as exn -> | ||
backoff_log ~exn ~name attempt None; | ||
Lwt.fail exn | ||
| exn -> | ||
let%lwt attempt = exp_backoff ?f_retry ~exn ~name ?max_retries ~max_delay attempt in | ||
loop f attempt | ||
in | ||
loop f 1 | ||
|
||
let exp_backoff_blocking ~master ~exn ~name ?max_retries ~max_delay attempt = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should use this opportunity to introduce "retry policy record" to group all(?) these arguments together |
||
match attempt, max_retries with | ||
| n, Some max_retries when n > max_retries -> | ||
backoff_log ~exn ~name attempt None; | ||
raise exn | ||
| attempt, _ -> | ||
let pause = exp_backoff_pause ~max_delay attempt in | ||
backoff_log ~exn ~name attempt (Some pause); | ||
wait_pause master pause; | ||
attempt + 1 | ||
|
||
let exp_backoff_blocking_no_poll ~exn ~name ?max_retries ~max_delay attempt = | ||
match attempt, max_retries with | ||
| n, Some max_retries when n > max_retries -> | ||
backoff_log ~exn ~name attempt None; | ||
raise exn | ||
| attempt, _ -> | ||
let pause = exp_backoff_pause ~max_delay attempt in | ||
backoff_log ~exn ~name attempt (Some pause); | ||
wait_pause' pause; | ||
attempt + 1 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
max_delay should be required here? @jorisgio
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems to always be used with this parameter specified in our codebase, I'm making it required.