module Data.ConnectionPool.Internal.ConnectionPool
( ConnectionPool(ConnectionPool, _handlerParams, _resourcePool)
, resourcePool
, handlerParams
, createConnectionPool
, destroyAllConnections
, withConnection
)
where
import Data.Function ((.))
import Data.Functor (Functor, (<$>))
import Data.Tuple (fst, uncurry)
import Data.Typeable (Typeable)
import System.IO (IO)
import Text.Show (Show(showsPrec), showChar, shows, showString)
import Control.Monad.Trans.Control (MonadBaseControl)
import Network.Socket (Socket)
import Data.Function.Between.Strict ((~@@^>))
import Data.Pool (Pool)
import qualified Data.Pool as Pool
( createPool
, destroyAllResources
, withResource
)
import Data.ConnectionPool.Internal.ResourcePoolParams (ResourcePoolParams)
import qualified Data.ConnectionPool.Internal.ResourcePoolParams
as ResourcePoolParams (ResourcePoolParams(..))
data ConnectionPool handlerParams a = ConnectionPool
{ _resourcePool :: !(Pool (Socket, a))
, _handlerParams :: !handlerParams
}
deriving (Typeable)
instance Show handlerParams => Show (ConnectionPool handlerParams a) where
showsPrec _ ConnectionPool{..} =
showString "ConnectionPool {resourcePool = " . shows _resourcePool
. showString ", handlerParams = " . shows _handlerParams . showChar '}'
resourcePool
:: Functor f
=> (Pool (Socket, a) -> f (Pool (Socket, b)))
-> ConnectionPool handlerParams a -> f (ConnectionPool handlerParams b)
resourcePool = _resourcePool ~@@^> \s b -> s{_resourcePool = b}
handlerParams
:: Functor f
=> (handlerParams -> f handlerParams')
-> ConnectionPool handlerParams c -> f (ConnectionPool handlerParams' c)
handlerParams = _handlerParams ~@@^> \s b -> s{_handlerParams = b}
createConnectionPool
:: handlerParams
-> IO (Socket, a)
-> (Socket -> IO ())
-> ResourcePoolParams
-> IO (ConnectionPool handlerParams a)
createConnectionPool hParams acquire release params =
mkConnectionPool <$> Pool.createPool
acquire
(release . fst)
(ResourcePoolParams._numberOfStripes params)
(ResourcePoolParams._resourceIdleTimeout params)
(ResourcePoolParams._numberOfResourcesPerStripe params)
where
mkConnectionPool pool = ConnectionPool
{ _resourcePool = pool
, _handlerParams = hParams
}
withConnection
:: MonadBaseControl IO m
=> ConnectionPool c a
-> (c -> Socket -> a -> m r)
-> m r
withConnection ConnectionPool{..} f =
Pool.withResource _resourcePool (uncurry (f _handlerParams))
destroyAllConnections :: ConnectionPool handlerParams a -> IO ()
destroyAllConnections ConnectionPool{_resourcePool} =
Pool.destroyAllResources _resourcePool