Retrying for humans using Haskell.
Go to file
Domen Kožar b4c5f0d9d1 fix ci?
2024-02-09 11:17:41 +00:00
.github/workflows fix ci? 2024-02-09 11:17:41 +00:00
src Add indefiniteDefaults 2024-01-23 13:21:55 +00:00
test fix intermittent test 2023-12-30 19:01:54 +00:00
.envrc README, devenv, compile it 2023-07-04 16:57:03 +01:00
.gitignore README, devenv, compile it 2023-07-04 16:57:03 +01:00
CHANGELOG.md v0.1.0.3 2024-01-26 20:55:55 +00:00
devenv.lock Implement Stamina.HTTP 2023-12-30 14:55:26 +00:00
devenv.nix Implement Stamina.HTTP 2023-12-30 14:55:26 +00:00
LICENSE Initial commit. 2023-07-04 15:38:37 +01:00
README.lhs implement Stamina 2023-12-30 11:38:00 +00:00
README.md Fix misspelling of "HTTP" 2024-01-05 03:45:26 -08:00
stack.yaml Implement Stamina.HTTP 2023-12-30 14:55:26 +00:00
stamina.cabal v0.1.0.3 2024-01-26 20:55:55 +00:00

Stamina

Active – The project has reached a stable, usable state and is being actively developed. Hackage CI status

A retry Haskell library for humans:

  • Exponential backoff with jitter between retries.
  • Limit the attempts of retries and total time.
  • Stamina.HTTP for retrying retriable Network.HTTP.Client exceptions respecting Retry-After headers.
  • Introspectable retry state for logging using RetryStatus, including the last exception that occurred.
  • Support resetting the retry state when for long-running tasks with an attempt that works.

API

Basics

  • Stamina.defaults :: (MonadIO m) => m RetrySettings
  • Stamina.RetryStatus = RetryStatus { attempts :: Int, delay :: NominalDiffTime, totalDelay :: NominalDiffTime, resetInitial :: IO (), lastException :: Maybe SomeException }
  • Stamina.retry :: (MonadCatch m, MonadIO m) => RetrySettings -> (RetryStatus -> m a) -> m a

Exceptions

  • Stamina.RetryAction = RaiseException | Retry | RetryDelay NominalDiffTime | RetryTime UTCTime
  • Stamina.retryFor :: (MonadCatch m, MonadIO m, Exception exc) => RetrySettings -> (exc -> m RetryAction) -> (RetryStatus -> m a) -> m a

HTTP

  • Stamina.HTTP.retry :: (MonadIO m, MonadCatch m) => Stamina.RetrySettings -> (Stamina.RetryStatus -> m a) -> m a

Basic example

import qualified Stamina
import Control.Monad.Catch (throwM)
import Control.Monad.IO.Class (MonadIO)

go :: IO ()
go = Stamina.retry Stamina.defaults $ \retryStatus -> do
  throwM $ userError "nope"

Example to catch specific exceptions


handler :: (MonadIO m) => IOError -> m Stamina.RetryAction
handler _ = return Stamina.Retry

go2 :: IO ()
go2 = Stamina.retryFor Stamina.defaults handler $ \retryStatus -> do
  throwM $ userError "nope"

Development

  1. Install devenv.sh.

  2. devenv shell

  3. stack build

Credits

Test setup
main = undefined