choonkeat/elm-retry/1.0.0

NOTE: the latest version is 1.0.1

Retry

Add retries to a task, based on a list of retry policies, until any one of the policies fail too.

type Policy x
= Policy (Int -> Policy x -> x -> Task x (Policy x))

A Policy is attached with a function that will return another Policy as a Task value.

The arguments of the function are

  • Int timestamp of when we first started originalTask, in milliseconds
  • Policy x the current policy; destructure to obtain the function to call
  • x last error from attempting originalTask

Refer to maxRetries source code for a simple example.

with : List (Policy x) -> Task x a -> Task x a

Given a list of error handling Policy we can make our originalTask retry on failure until any one of the Policy fails.

policy =
    [ Retry.maxDuration 7000
    , Retry.exponentialBackoff { interval = 500, maxInterval = 3000 }
    ]


originalTask
    |> Retry.with policy
    |> Task.attempt DidTask

Common policies

maxRetries : Int -> Policy x

Stop retrying originalTask after a number of retries.

Retry.with [ Retry.maxRetries 20 ] originalTask
    |> Task.attempt DidOriginalTask

NOTE: The code above does NOT sleep between retries; best to combine with constantInterval or exponentialBackoff

maxDuration : Int -> Policy x

Stop retrying originalTask after some number of milliseconds.

Retry.with [ Retry.maxDuration 7000 ] originalTask
    |> Task.attempt DidOriginalTask

NOTE: The code above does NOT sleep between retries; best to combine with constantInterval or exponentialBackoff

Sleep for the same number of milliseconds before every retry.

Retry.with [ Retry.constantInterval 1000 ] originalTask
    |> Task.attempt DidOriginalTask

NOTE: The code above will keep retrying originalTask; best to combine with maxRetries or maxDuration

{ interval : Float
, maxInterval : Float
}
-> Policy x

Sleep for an increasing number of milliseconds before every retry. Backoff algorithim is based off https://github.com/cenkalti/backoff

Retry.with [ Retry.exponentialBackoff { interval = 500, maxInterval = 3000 } ] originalTask
    |> Task.attempt DidOriginalTask

NOTE: The code above will keep retrying originalTask; best to combine with maxRetries or maxDuration