module UnliftIO.Pool
  ( Pool
  , P.PoolConfig
  , P.setNumStripes
  , LocalPool
  , mkDefaultPoolConfig
  , newPool
  , withResource
  , takeResource
  , tryWithResource
  , tryTakeResource
  , destroyResource
  , putResource
  , destroyAllResources
  ) where

import           Control.Monad.IO.Unlift (MonadUnliftIO(..), liftIO, unliftIO)
import qualified Data.Pool as P
import           Data.Pool (PoolConfig)

type Pool = P.Pool

type LocalPool = P.LocalPool

mkDefaultPoolConfig :: MonadUnliftIO m => m a -> (a -> m ()) -> Double -> Int -> m (PoolConfig a)
mkDefaultPoolConfig :: forall (m :: * -> *) a.
MonadUnliftIO m =>
m a -> (a -> m ()) -> Double -> Int -> m (PoolConfig a)
mkDefaultPoolConfig m a
create a -> m ()
destroy Double
keepAlive Int
maxOpen =
  forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
io ->
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. IO a -> (a -> IO ()) -> Double -> Int -> PoolConfig a
P.defaultPoolConfig (forall a. m a -> IO a
io m a
create) (forall a. m a -> IO a
io forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m ()
destroy) Double
keepAlive Int
maxOpen

-- | Lifted version of 'P.newPool'
--
-- @since 0.4.2.0
newPool :: MonadUnliftIO m => PoolConfig a -> m (Pool a)
newPool :: forall (m :: * -> *) a.
MonadUnliftIO m =>
PoolConfig a -> m (Pool a)
newPool PoolConfig a
config =
  forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
io ->
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. PoolConfig a -> IO (Pool a)
P.newPool PoolConfig a
config

withResource :: MonadUnliftIO m => Pool a -> (a -> m b) -> m b
withResource :: forall (m :: * -> *) a b.
MonadUnliftIO m =>
Pool a -> (a -> m b) -> m b
withResource Pool a
pool a -> m b
action =
  forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
io ->
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a r. Pool a -> (a -> IO r) -> IO r
P.withResource Pool a
pool forall a b. (a -> b) -> a -> b
$ \a
a ->
      forall a. m a -> IO a
io forall a b. (a -> b) -> a -> b
$ a -> m b
action a
a

takeResource :: MonadUnliftIO m => Pool a -> m (a, LocalPool a)
takeResource :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Pool a -> m (a, LocalPool a)
takeResource Pool a
pool = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Pool a -> IO (a, LocalPool a)
P.takeResource Pool a
pool

tryWithResource :: MonadUnliftIO m => Pool a -> (a -> m b) -> m (Maybe b)
tryWithResource :: forall (m :: * -> *) a b.
MonadUnliftIO m =>
Pool a -> (a -> m b) -> m (Maybe b)
tryWithResource Pool a
pool a -> m b
action =
  forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
io ->
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a r. Pool a -> (a -> IO r) -> IO (Maybe r)
P.tryWithResource Pool a
pool forall a b. (a -> b) -> a -> b
$ \a
a ->
      forall a. m a -> IO a
io forall a b. (a -> b) -> a -> b
$ a -> m b
action a
a

tryTakeResource :: MonadUnliftIO m => Pool a -> m (Maybe (a, LocalPool a))
tryTakeResource :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Pool a -> m (Maybe (a, LocalPool a))
tryTakeResource Pool a
pool = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Pool a -> IO (Maybe (a, LocalPool a))
P.tryTakeResource Pool a
pool

destroyResource :: MonadUnliftIO m => Pool a -> LocalPool a -> a -> m ()
destroyResource :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Pool a -> LocalPool a -> a -> m ()
destroyResource Pool a
pool LocalPool a
localPool a
a = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Pool a -> LocalPool a -> a -> IO ()
P.destroyResource Pool a
pool LocalPool a
localPool a
a

putResource :: MonadUnliftIO m => LocalPool a -> a -> m ()
putResource :: forall (m :: * -> *) a. MonadUnliftIO m => LocalPool a -> a -> m ()
putResource LocalPool a
localPool a
a = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. LocalPool a -> a -> IO ()
P.putResource LocalPool a
localPool a
a

destroyAllResources :: MonadUnliftIO m => Pool a -> m ()
destroyAllResources :: forall (m :: * -> *) a. MonadUnliftIO m => Pool a -> m ()
destroyAllResources Pool a
pool = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Pool a -> IO ()
P.destroyAllResources Pool a
pool