Skip to content

Instantly share code, notes, and snippets.

@imsaravana369
Last active October 6, 2023 15:39
Show Gist options
  • Save imsaravana369/4113a7927630d21837790298e27a239e to your computer and use it in GitHub Desktop.
Save imsaravana369/4113a7927630d21837790298e27a239e to your computer and use it in GitHub Desktop.
An example snippet that shows how api can be retried in a neat way using the `purescript-aff-retry` module
module Main where
-- To Try in trypurescript editor : https://shorturl.at/ghqw9
import Prelude
import Effect
import Effect.Aff.Retry
import Effect.Aff
import Data.Time.Duration(Seconds(..))
import Data.Newtype(wrap)
import Effect.Random(randomInt, randomBool)
import Effect.Class(liftEffect)
import Data.Array(elem)
import Debug(traceM)
import Data.Either(Either(..), either, isLeft)
type ApiResponse = Either String Int
myApi :: Aff ApiResponse
myApi = do
val <- delay $ wrap 1000.0
res <- liftEffect $ randomInt 1 20
let isSuccess = res `mod` 4 == 0
-- simulating api error
pure $ if isSuccess
then Right res
else Left $ "Bad response " <> (show res)
makeApiCallWithRetry :: Aff ApiResponse -> Aff ApiResponse
makeApiCallWithRetry apiCall = retrying policy shouldRetry action
where
--- max amount of retry is 5 + the delay will grow exponentially
policy :: RetryPolicy
policy = limitRetries 5 <> exponentialBackoff (Seconds 1.0)
-- this function tells when to retry - return True to retry
shouldRetry :: RetryStatus -> ApiResponse -> Aff Boolean
shouldRetry (RetryStatus retryStatus) response = do
traceM $ "Retrying for :" <> (show retryStatus.iterNumber)
traceM $ "Retry Duration: " <> (show retryStatus.previousDelay)
pure $ isLeft response
-- the action that will get retried
action :: RetryStatus -> Aff ApiResponse
action (RetryStatus status) = do
traceM "Making ApiCall..."
res <- apiCall
traceM $ "Received response :" <> (show res)
traceM $ "Already waited for : " <> (show status.cumulativeDelay)
pure res
main :: Effect Unit
main = do
runAff_ (either (traceM <<< show) (traceM <<< show)) $ makeApiCallWithRetry myApi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment