-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.

{-# LANGUAGE OverloadedStrings #-}

module Database.Redis.IO.Settings where

import Data.Time
import Data.Word
import Database.Redis.IO.Types (Milliseconds (..))

data Settings = Settings
    { Settings -> String
sHost            :: !String
    , Settings -> Word16
sPort            :: !Word16
    , Settings -> NominalDiffTime
sIdleTimeout     :: !NominalDiffTime
    , Settings -> Int
sMaxConnections  :: !Int
    , Settings -> Int
sPoolStripes     :: !Int
    , Settings -> Milliseconds
sConnectTimeout  :: !Milliseconds
    , Settings -> Milliseconds
sSendRecvTimeout :: !Milliseconds
    }

-- | Default settings.
--
-- * host = localhost
-- * port = 6379
-- * idle timeout = 60s
-- * stripes = 2
-- * connections per stripe = 25
-- * connect timeout = 5s
-- * send-receive timeout = 10s
defSettings :: Settings
defSettings :: Settings
defSettings = String
-> Word16
-> NominalDiffTime
-> Int
-> Int
-> Milliseconds
-> Milliseconds
-> Settings
Settings String
"localhost" Word16
6379
    NominalDiffTime
60    -- idle timeout
    Int
50    -- max connections per stripe
    Int
2     -- max stripes
    Milliseconds
5000  -- connect timeout
    Milliseconds
10000 -- send and recv timeout (sum)

setHost :: String -> Settings -> Settings
setHost :: String -> Settings -> Settings
setHost String
v Settings
s = Settings
s { sHost :: String
sHost = String
v }

setPort :: Word16 -> Settings -> Settings
setPort :: Word16 -> Settings -> Settings
setPort Word16
v Settings
s = Settings
s { sPort :: Word16
sPort = Word16
v }

setIdleTimeout :: NominalDiffTime -> Settings -> Settings
setIdleTimeout :: NominalDiffTime -> Settings -> Settings
setIdleTimeout NominalDiffTime
v Settings
s = Settings
s { sIdleTimeout :: NominalDiffTime
sIdleTimeout = NominalDiffTime
v }

-- | Maximum connections per pool stripe.
setMaxConnections :: Int -> Settings -> Settings
setMaxConnections :: Int -> Settings -> Settings
setMaxConnections Int
v Settings
s = Settings
s { sMaxConnections :: Int
sMaxConnections = Int
v }

setPoolStripes :: Int -> Settings -> Settings
setPoolStripes :: Int -> Settings -> Settings
setPoolStripes Int
v Settings
s
    | Int
v Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1     = String -> Settings
forall a. HasCallStack => String -> a
error String
"Network.Redis.IO.Settings: at least one stripe required"
    | Bool
otherwise = Settings
s { sPoolStripes :: Int
sPoolStripes = Int
v }

-- | When a pool connection is opened, connect timeout is the maximum time
-- we are willing to wait for the connection attempt to the redis server to
-- succeed.
setConnectTimeout :: NominalDiffTime -> Settings -> Settings
setConnectTimeout :: NominalDiffTime -> Settings -> Settings
setConnectTimeout NominalDiffTime
v Settings
s = Settings
s { sConnectTimeout :: Milliseconds
sConnectTimeout = Int -> Milliseconds
Ms (Int -> Milliseconds) -> Int -> Milliseconds
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (NominalDiffTime
1000 NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Num a => a -> a -> a
* NominalDiffTime
v) }

setSendRecvTimeout :: NominalDiffTime -> Settings -> Settings
setSendRecvTimeout :: NominalDiffTime -> Settings -> Settings
setSendRecvTimeout NominalDiffTime
v Settings
s = Settings
s { sSendRecvTimeout :: Milliseconds
sSendRecvTimeout = Int -> Milliseconds
Ms (Int -> Milliseconds) -> Int -> Milliseconds
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (NominalDiffTime
1000 NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Num a => a -> a -> a
* NominalDiffTime
v) }