Retries for tasks and manually managed values, support exponential backoff.
Again.TaskFetch /message.txt with up to three attempts, retrying transient HTTP failures. ReceivedMessage carries the final result to update.
import Again.Http
import Again.Policy as Policy
import Again.Schedule exposing (Schedule(..))
import Again.Task
import Http
import Task
type Msg
= ReceivedMessage (Result Http.Error String)
loadMessage : Cmd Msg
loadMessage =
Http.task
{ method = "GET"
, headers = []
, url = "/message.txt"
, body = Http.emptyBody
, resolver = Http.stringResolver Again.Http.resolve
, timeout = Just 5000
}
|> Again.Task.retryIf Again.Http.isRetryable
{ schedule = Periodic { delay = 1000 }
, limit = Policy.MaxAttempts 3
}
|> Task.attempt ReceivedMessageAgain.RemoteA successful Remote can later fail, such as a connection that closes.
Poll a submitted job: retry on 202 Accepted, finish on 200 OK, and stop on other responses:
import Again.Decision as Decision
import Again.Policy as Policy
import Again.Remote as Remote
import Again.Remote.Cmd as RemoteCmd
import Again.Schedule exposing (Schedule(..))
import Http
type PollError
= NotReady String
| RequestFailed (Http.Response String)
type alias Model =
Remote.Remote PollError String
type Msg
= Received (Result PollError String)
| PollAgain
init : ( Model, Cmd Msg )
init =
( Remote.init (Policy.unlimited (Periodic { delay = 1000 }))
|> Remote.withRetryable decide
, poll
)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Received (Ok output) ->
( Remote.succeed output model, Cmd.none )
Received (Err error) ->
RemoteCmd.fail PollAgain error model
PollAgain ->
( Remote.beginRetry model, poll )
decide : PollError -> Decision.Decision
decide error =
case error of
NotReady _ ->
Decision.Retry
RequestFailed _ ->
Decision.Stop
poll : Cmd Msg
poll =
Http.get
{ url = "/jobs/42"
, expect = Http.expectStringResponse Received readStatus
}
readStatus : Http.Response String -> Result PollError String
readStatus response =
case response of
Http.GoodStatus_ metadata body ->
case metadata.statusCode of
200 ->
Ok body
202 ->
Err (NotReady body)
_ ->
Err (RequestFailed response)
_ ->
Err (RequestFailed response)