-- | Private helper functions. Note that all contents of this module are excluded from the versioning scheme.
{-# LANGUAGE BangPatterns #-}
module OpenAI.Client.Internal.Helpers where

import Network.HTTP.Types.Status
import Servant.Client

runRequest :: Int -> Int -> IO (Either ClientError a) -> IO (Either ClientError a)
runRequest :: Int
-> Int -> IO (Either ClientError a) -> IO (Either ClientError a)
runRequest Int
maxRetries !Int
retryCount IO (Either ClientError a)
makeRequest =
  do Either ClientError a
res <- IO (Either ClientError a)
makeRequest
     case Either ClientError a
res of
       Right a
ok -> Either ClientError a -> IO (Either ClientError a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Either ClientError a
forall a b. b -> Either a b
Right a
ok)
       Left err :: ClientError
err@(ConnectionError SomeException
_) -> ClientError -> IO (Either ClientError a)
maybeRetry ClientError
err
       Left err :: ClientError
err@(FailureResponse RequestF () (BaseUrl, ByteString)
_ Response
resp)
         | Response -> Status
forall a. ResponseF a -> Status
responseStatusCode Response
resp Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
== Status
conflict409 -> ClientError -> IO (Either ClientError a)
maybeRetry ClientError
err
         | Status -> Int
statusCode (Response -> Status
forall a. ResponseF a -> Status
responseStatusCode Response
resp) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
500 -> ClientError -> IO (Either ClientError a)
maybeRetry ClientError
err
         | Bool
otherwise -> Either ClientError a -> IO (Either ClientError a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ClientError -> Either ClientError a
forall a b. a -> Either a b
Left ClientError
err)
       Left ClientError
err -> Either ClientError a -> IO (Either ClientError a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ClientError -> Either ClientError a
forall a b. a -> Either a b
Left ClientError
err)
  where
    maybeRetry :: ClientError -> IO (Either ClientError a)
maybeRetry ClientError
err =
      if Int
retryCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
maxRetries
      then Either ClientError a -> IO (Either ClientError a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ClientError -> Either ClientError a
forall a b. a -> Either a b
Left ClientError
err)
      else Int
-> Int -> IO (Either ClientError a) -> IO (Either ClientError a)
forall a.
Int
-> Int -> IO (Either ClientError a) -> IO (Either ClientError a)
runRequest Int
maxRetries (Int
retryCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) IO (Either ClientError a)
makeRequest