{-# LANGUAGE BangPatterns #-}

-- | Private helper functions. Note that all contents of this module are excluded from the versioning scheme.
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