Skip to content

Instantly share code, notes, and snippets.

@jbrestan
Last active January 10, 2018 13:07
Show Gist options
  • Save jbrestan/59e27c5a3048bf4ba6eca48d2ae03049 to your computer and use it in GitHub Desktop.
Save jbrestan/59e27c5a3048bf4ba6eca48d2ae03049 to your computer and use it in GitHub Desktop.
Thoroughly shaven yak
module ExponentialBackoff =
open System
[<Measure>] type ms
type Backoff =
| Immediate
| Initial
| Double of previousDelay: int<ms>
let backoff (initialDelay: TimeSpan) (maximumDelay: TimeSpan) =
let inline intms x = int x |> LanguagePrimitives.Int32WithMeasure<ms>
let initialDelay = intms initialDelay.TotalMilliseconds
let maximumDelay = intms maximumDelay.TotalMilliseconds
let inline calcDelay (x:int<ms>) = List.max [ 0; List.min [ x * 2; maximumDelay ] ]
let inline sleep x = int x |> Async.Sleep
fun nextBackoff -> async {
match nextBackoff with
| Immediate ->
return Initial
| Initial ->
do! sleep initialDelay
return Double initialDelay
| Double previousDelay ->
let currentDelay = calcDelay previousDelay
do! sleep currentDelay
return Double currentDelay
}
@jbrestan
Copy link
Author

This is far less cool

    let backoff initial max current = async {
        if current > 0. then 
            let current' = Math.Max(Math.Min(max, current), 0.)
            do! Async.Sleep <| int current'
            return current' * 2.
        else
            return initial
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment