Exponential backoff retry logic
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(lint): remove redundant function prefixes (E331)

Strip get_/make_/find_/create_ from 138 function definitions and all
call sites across ocaml-pds, ocaml-pid1, ocaml-precommit,
ocaml-publicsuffix, ocaml-qemu, ocaml-requests, ocaml-retry, and
ocaml-rpmsg. Use Module.v for constructors per the E331 convention.

+46 -50
+2 -2
lib/retry.ml
··· 17 17 let default_config = 18 18 { max_retries = 3; backoff_factor = 0.3; backoff_max = 120.0; jitter = true } 19 19 20 - let create_config ?(max_retries = 3) ?(backoff_factor = 0.3) 21 - ?(backoff_max = 120.0) ?(jitter = true) () = 20 + let config ?(max_retries = 3) ?(backoff_factor = 0.3) ?(backoff_max = 120.0) 21 + ?(jitter = true) () = 22 22 Log.debug (fun m -> 23 23 m "Creating retry config: max_retries=%d backoff_factor=%.2f jitter=%b" 24 24 max_retries backoff_factor jitter);
+2 -2
lib/retry.mli
··· 10 10 11 11 {1 Example} 12 12 {[ 13 - let config = Retry.create_config ~max_retries:5 () in 13 + let config = Retry.config ~max_retries:5 () in 14 14 let should_retry = function 15 15 | Eio.Net.Connection_refused _ -> true 16 16 | _ -> false ··· 30 30 val default_config : config 31 31 (** Default configuration with 3 retries, 0.3s backoff factor, 120s max. *) 32 32 33 - val create_config : 33 + val config : 34 34 ?max_retries:int -> 35 35 ?backoff_factor:float -> 36 36 ?backoff_max:float ->
+42 -46
test/test.ml
··· 7 7 Alcotest.(check (float 0.01)) "backoff_max" 120.0 config.backoff_max; 8 8 Alcotest.(check bool) "jitter" true config.jitter 9 9 10 - let test_create_config_defaults () = 11 - let config = Retry.create_config () in 10 + let test_config_defaults () = 11 + let config = Retry.config () in 12 12 Alcotest.(check int) "max_retries" 3 config.max_retries; 13 13 Alcotest.(check (float 0.01)) "backoff_factor" 0.3 config.backoff_factor; 14 14 Alcotest.(check (float 0.01)) "backoff_max" 120.0 config.backoff_max; 15 15 Alcotest.(check bool) "jitter" true config.jitter 16 16 17 - let test_create_config_custom () = 17 + let test_config_custom () = 18 18 let config = 19 - Retry.create_config ~max_retries:10 ~backoff_factor:1.0 ~backoff_max:60.0 19 + Retry.config ~max_retries:10 ~backoff_factor:1.0 ~backoff_max:60.0 20 20 ~jitter:false () 21 21 in 22 22 Alcotest.(check int) "max_retries" 10 config.max_retries; ··· 24 24 Alcotest.(check (float 0.01)) "backoff_max" 60.0 config.backoff_max; 25 25 Alcotest.(check bool) "jitter" false config.jitter 26 26 27 - let test_create_config_partial () = 28 - let config = Retry.create_config ~max_retries:5 ~jitter:false () in 27 + let test_config_partial () = 28 + let config = Retry.config ~max_retries:5 ~jitter:false () in 29 29 Alcotest.(check int) "max_retries" 5 config.max_retries; 30 30 Alcotest.(check (float 0.01)) "backoff_factor" 0.3 config.backoff_factor; 31 31 Alcotest.(check (float 0.01)) "backoff_max" 120.0 config.backoff_max; ··· 33 33 34 34 let test_pp_config () = 35 35 let config = 36 - Retry.create_config ~max_retries:5 ~backoff_factor:0.5 ~backoff_max:30.0 36 + Retry.config ~max_retries:5 ~backoff_factor:0.5 ~backoff_max:30.0 37 37 ~jitter:true () 38 38 in 39 39 let output = Format.asprintf "%a" Retry.pp_config config in ··· 82 82 83 83 let test_backoff_test_vectors () = 84 84 let config = 85 - Retry.create_config ~backoff_factor:1.0 ~backoff_max:10000.0 ~jitter:false 86 - () 85 + Retry.config ~backoff_factor:1.0 ~backoff_max:10000.0 ~jitter:false () 87 86 in 88 87 List.iter 89 88 (fun (attempt, expected) -> ··· 123 122 124 123 let test_backoff_default_config_vectors () = 125 124 let config = 126 - Retry.create_config ~backoff_factor:0.3 ~backoff_max:120.0 ~jitter:false () 125 + Retry.config ~backoff_factor:0.3 ~backoff_max:120.0 ~jitter:false () 127 126 in 128 127 List.iter 129 128 (fun (attempt, expected) -> ··· 158 157 159 158 let test_backoff_aws_style () = 160 159 let config = 161 - Retry.create_config ~backoff_factor:0.1 ~backoff_max:10.0 ~jitter:false () 160 + Retry.config ~backoff_factor:0.1 ~backoff_max:10.0 ~jitter:false () 162 161 in 163 162 List.iter 164 163 (fun (attempt, expected) -> ··· 184 183 185 184 let test_backoff_gcp_style () = 186 185 let config = 187 - Retry.create_config ~backoff_factor:1.0 ~backoff_max:32.0 ~jitter:false () 186 + Retry.config ~backoff_factor:1.0 ~backoff_max:32.0 ~jitter:false () 188 187 in 189 188 List.iter 190 189 (fun (attempt, expected) -> ··· 196 195 197 196 let test_backoff_no_jitter () = 198 197 let config = 199 - Retry.create_config ~backoff_factor:1.0 ~backoff_max:1000.0 ~jitter:false () 198 + Retry.config ~backoff_factor:1.0 ~backoff_max:1000.0 ~jitter:false () 200 199 in 201 200 (* attempt 1: 1.0 * 2^1 = 2.0 *) 202 201 let delay1 = Retry.calculate_backoff ~config ~attempt:1 in ··· 210 209 211 210 let test_backoff_exponential () = 212 211 let config = 213 - Retry.create_config ~backoff_factor:0.5 ~backoff_max:1000.0 ~jitter:false () 212 + Retry.config ~backoff_factor:0.5 ~backoff_max:1000.0 ~jitter:false () 214 213 in 215 214 (* attempt 1: 0.5 * 2^1 = 1.0 *) 216 215 let delay1 = Retry.calculate_backoff ~config ~attempt:1 in ··· 224 223 225 224 let test_backoff_capped () = 226 225 let config = 227 - Retry.create_config ~backoff_factor:1.0 ~backoff_max:5.0 ~jitter:false () 226 + Retry.config ~backoff_factor:1.0 ~backoff_max:5.0 ~jitter:false () 228 227 in 229 228 (* attempt 1: min(2.0, 5.0) = 2.0 *) 230 229 let delay1 = Retry.calculate_backoff ~config ~attempt:1 in ··· 241 240 242 241 let test_backoff_with_jitter () = 243 242 let config = 244 - Retry.create_config ~backoff_factor:1.0 ~backoff_max:1000.0 ~jitter:true () 243 + Retry.config ~backoff_factor:1.0 ~backoff_max:1000.0 ~jitter:true () 245 244 in 246 245 (* With jitter, delay is base + random(0, base), so between base and 2*base *) 247 246 (* attempt 1: base = 2.0, so delay in [2.0, 4.0) *) ··· 256 255 257 256 let test_backoff_zero_factor () = 258 257 let config = 259 - Retry.create_config ~backoff_factor:0.0 ~backoff_max:1000.0 ~jitter:false () 258 + Retry.config ~backoff_factor:0.0 ~backoff_max:1000.0 ~jitter:false () 260 259 in 261 260 let delay = Retry.calculate_backoff ~config ~attempt:5 in 262 261 Alcotest.(check (float 0.01)) "zero factor gives zero delay" 0.0 delay 263 262 264 263 let test_backoff_attempt_zero () = 265 264 let config = 266 - Retry.create_config ~backoff_factor:1.0 ~backoff_max:1000.0 ~jitter:false () 265 + Retry.config ~backoff_factor:1.0 ~backoff_max:1000.0 ~jitter:false () 267 266 in 268 267 (* attempt 0: 1.0 * 2^0 = 1.0 *) 269 268 let delay = Retry.calculate_backoff ~config ~attempt:0 in ··· 274 273 let test_success_first_try () = 275 274 Eio_main.run @@ fun env -> 276 275 let clock = Eio.Stdenv.clock env in 277 - let config = Retry.create_config ~max_retries:3 () in 276 + let config = Retry.config ~max_retries:3 () in 278 277 let calls = ref 0 in 279 278 let result = 280 279 Retry.with_retry ~clock ~config ··· 290 289 Eio_main.run @@ fun env -> 291 290 let clock = Eio.Stdenv.clock env in 292 291 let config = 293 - Retry.create_config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 292 + Retry.config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 294 293 in 295 294 let calls = ref 0 in 296 295 let result = ··· 308 307 Eio_main.run @@ fun env -> 309 308 let clock = Eio.Stdenv.clock env in 310 309 let config = 311 - Retry.create_config ~max_retries:2 ~backoff_factor:0.001 ~jitter:false () 310 + Retry.config ~max_retries:2 ~backoff_factor:0.001 ~jitter:false () 312 311 in 313 312 let calls = ref 0 in 314 313 let raised = ··· 330 329 Eio_main.run @@ fun env -> 331 330 let clock = Eio.Stdenv.clock env in 332 331 let config = 333 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 332 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 334 333 in 335 334 let calls = ref 0 in 336 335 let raised = ··· 352 351 Eio_main.run @@ fun env -> 353 352 let clock = Eio.Stdenv.clock env in 354 353 let config = 355 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 354 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 356 355 in 357 356 let calls = ref 0 in 358 357 let should_retry = function ··· 372 371 Eio_main.run @@ fun env -> 373 372 let clock = Eio.Stdenv.clock env in 374 373 let config = 375 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 374 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 376 375 in 377 376 let calls = ref 0 in 378 377 let should_retry = function ··· 396 395 Eio_main.run @@ fun env -> 397 396 let clock = Eio.Stdenv.clock env in 398 397 let config = 399 - Retry.create_config ~max_retries:0 ~backoff_factor:0.001 ~jitter:false () 398 + Retry.config ~max_retries:0 ~backoff_factor:0.001 ~jitter:false () 400 399 in 401 400 let calls = ref 0 in 402 401 let raised = ··· 418 417 Eio_main.run @@ fun env -> 419 418 let clock = Eio.Stdenv.clock env in 420 419 let config = 421 - Retry.create_config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 420 + Retry.config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 422 421 in 423 422 let calls = ref 0 in 424 423 let result = ··· 436 435 Eio_main.run @@ fun env -> 437 436 let clock = Eio.Stdenv.clock env in 438 437 let config = 439 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 438 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 440 439 in 441 440 let calls = ref 0 in 442 441 let should_retry = function ··· 461 460 Eio_main.run @@ fun env -> 462 461 let clock = Eio.Stdenv.clock env in 463 462 let config = 464 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 463 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 465 464 in 466 465 let calls = ref 0 in 467 466 let should_retry = function Failure _ -> true | _ -> false in ··· 483 482 let test_result_success_first_try () = 484 483 Eio_main.run @@ fun env -> 485 484 let clock = Eio.Stdenv.clock env in 486 - let config = Retry.create_config ~max_retries:3 () in 485 + let config = Retry.config ~max_retries:3 () in 487 486 let calls = ref 0 in 488 487 let result = 489 488 Retry.with_retry_result ~clock ~config ··· 499 498 Eio_main.run @@ fun env -> 500 499 let clock = Eio.Stdenv.clock env in 501 500 let config = 502 - Retry.create_config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 501 + Retry.config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 503 502 in 504 503 let calls = ref 0 in 505 504 let result = ··· 516 515 Eio_main.run @@ fun env -> 517 516 let clock = Eio.Stdenv.clock env in 518 517 let config = 519 - Retry.create_config ~max_retries:2 ~backoff_factor:0.001 ~jitter:false () 518 + Retry.config ~max_retries:2 ~backoff_factor:0.001 ~jitter:false () 520 519 in 521 520 let calls = ref 0 in 522 521 let result = ··· 533 532 Eio_main.run @@ fun env -> 534 533 let clock = Eio.Stdenv.clock env in 535 534 let config = 536 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 535 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 537 536 in 538 537 let calls = ref 0 in 539 538 let result = ··· 550 549 Eio_main.run @@ fun env -> 551 550 let clock = Eio.Stdenv.clock env in 552 551 let config = 553 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 552 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 554 553 in 555 554 let calls = ref 0 in 556 555 let should_retry err = String.equal err "transient" in ··· 566 565 Eio_main.run @@ fun env -> 567 566 let clock = Eio.Stdenv.clock env in 568 567 let config = 569 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 568 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 570 569 in 571 570 let calls = ref 0 in 572 571 let should_retry err = String.equal err "transient" in ··· 582 581 Eio_main.run @@ fun env -> 583 582 let clock = Eio.Stdenv.clock env in 584 583 let config = 585 - Retry.create_config ~max_retries:0 ~backoff_factor:0.001 ~jitter:false () 584 + Retry.config ~max_retries:0 ~backoff_factor:0.001 ~jitter:false () 586 585 in 587 586 let calls = ref 0 in 588 587 let result = ··· 599 598 Eio_main.run @@ fun env -> 600 599 let clock = Eio.Stdenv.clock env in 601 600 let config = 602 - Retry.create_config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 601 + Retry.config ~max_retries:3 ~backoff_factor:0.001 ~jitter:false () 603 602 in 604 603 let calls = ref 0 in 605 604 let result = ··· 630 629 Eio_main.run @@ fun env -> 631 630 let clock = Eio.Stdenv.clock env in 632 631 let config = 633 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 632 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 634 633 in 635 634 let calls = ref 0 in 636 635 let should_retry = function ··· 655 654 Eio_main.run @@ fun env -> 656 655 let clock = Eio.Stdenv.clock env in 657 656 let config = 658 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 657 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 659 658 in 660 659 let calls = ref 0 in 661 660 let should_retry = function ··· 676 675 Eio_main.run @@ fun env -> 677 676 let clock = Eio.Stdenv.clock env in 678 677 let config = 679 - Retry.create_config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 678 + Retry.config ~max_retries:5 ~backoff_factor:0.001 ~jitter:false () 680 679 in 681 680 let calls = ref 0 in 682 681 let should_retry = function ··· 699 698 Eio_main.run @@ fun env -> 700 699 let clock = Eio.Stdenv.clock env in 701 700 let config = 702 - Retry.create_config ~max_retries:20 ~backoff_factor:0.0001 ~jitter:false () 701 + Retry.config ~max_retries:20 ~backoff_factor:0.0001 ~jitter:false () 703 702 in 704 703 let calls = ref 0 in 705 704 let result = ··· 719 718 ( "config", 720 719 [ 721 720 Alcotest.test_case "default config" `Quick test_default_config; 722 - Alcotest.test_case "create config defaults" `Quick 723 - test_create_config_defaults; 724 - Alcotest.test_case "create config custom" `Quick 725 - test_create_config_custom; 726 - Alcotest.test_case "create config partial" `Quick 727 - test_create_config_partial; 721 + Alcotest.test_case "config defaults" `Quick test_config_defaults; 722 + Alcotest.test_case "config custom" `Quick test_config_custom; 723 + Alcotest.test_case "config partial" `Quick test_config_partial; 728 724 Alcotest.test_case "pp_config" `Quick test_pp_config; 729 725 ] ); 730 726 ( "backoff",