Skip to content

Commit

Permalink
Add reset
Browse files Browse the repository at this point in the history
  • Loading branch information
domenkozar committed Dec 21, 2023
1 parent 8344309 commit 4510cae
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 19 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ A retry Haskell library for humans:
- Limit the **attempts** of retries and **total** time.
- `Stamina.HTTP` for retrying retriable `Network.HTTP.Client` exceptions.
- Introspectable retry state for logging using `RetryStatus`.
- Support resetting the retry state when the action is long-running and an attempt works.

## API

Expand Down Expand Up @@ -37,7 +38,10 @@ retryOnExceptions :: (Exception e, MonadIO m)
-> (RetryStatus -> m a)
-> m a

data RetryAction = Skip | Retry | RetryAfter Int
data RetryAction =
Skip -- Propagate the exception.
| Retry -- Retry with the delay according to the settings.
| RetryDelay DiffTime -- Retry after the given delay.
```

## Example
Expand All @@ -64,4 +68,4 @@ main = do
## Credits

- Heavily inspired by [stamina for Python](https://stamina.hynek.me/en/stable/tutorial.html#retries).
- [retry](https://github.com/Soostone/retry) as case study for what needs to be supported.
- [retry](https://github.com/Soostone/retry) as case study for what needs to be supported.
33 changes: 17 additions & 16 deletions src/Stamina.hs
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
{- A retry library should be able to:
- Wait between your retries: this is called a backoff.
- Not retry simultaneously with all your clients, so you must introduce randomness into your backoff: a jitter.
- Not retry forever. Sometimes a remote service is down indefinitely, and you must deal with it.
Inspired by https://stamina.hynek.me/en/stable/api.html
-}
module Stamina
( retry,
retryOnExceptions,
Expand All @@ -18,6 +10,7 @@ where

import Control.Exception (Exception, Handler)
import Control.Monad.IO.Class (MonadIO)
import Control.Retry qualified as Retry
import Data.Time.Clock (DiffTime)

data RetrySettings = RetrySettings
Expand All @@ -34,16 +27,24 @@ data RetrySettings = RetrySettings
-- Tracks the status of a retry
-- All fields will be zero if no retries have been attempted yet.
data RetryStatus = RetryStatus
{ attempts :: Int,
delay :: DiffTime,
totalDelay :: DiffTime
{ attempts :: Int, -- Number of retry attempts so far.
delay :: DiffTime, -- Delay before the next retry.
totalDelay :: DiffTime, -- Total delay so far.
reset :: IO () -- Reset the retry status to the initial state.
}
deriving (Show)

defaults :: RetrySettings
defaults =
-- TODO: Implement reset
RetrySettings
{ initialRetryStatus = RetryStatus {attempts = 0, delay = 0, totalDelay = 0},
{ initialRetryStatus =
RetryStatus
{ attempts = 0,
delay = 0,
totalDelay = 0,
reset = pure ()
},
maxAttempts = 10,
maxTime = 45.0,
backoffInitialRetryDelay = 0.1,
Expand All @@ -52,10 +53,10 @@ defaults =
backoffExpBase = 2.0
}

data RetryAction =
Skip -- Propagate the exception.
| Retry -- Retry with the delay according to the settings.
| RetryDelay DiffTime -- Retry after the given delay.
data RetryAction
= Skip -- Propagate the exception.
| Retry -- Retry with the delay according to the settings.
| RetryDelay DiffTime -- Retry after the given delay.

-- | Retry on all sync exceptions, async exceptions will still be thrown.
--
Expand Down
2 changes: 1 addition & 1 deletion stamina.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ library
-- other-extensions:

-- Other library packages from which modules are imported.
build-depends: base, http-client, time
build-depends: base, http-client, time, retry

-- Directories containing source files.
hs-source-dirs: src
Expand Down

0 comments on commit 4510cae

Please sign in to comment.