resource-pool-catchio- Fork of resource-pool, with a MonadCatchIO constraint

MaintainerBryan O'Sullivan <>
Safe HaskellSafe-Infered



A high-performance striped pooling abstraction for managing flexibly-sized collections of resources such as database connections.

"Striped" means that a single Pool consists of several sub-pools, each managed independently. A stripe size of 1 is fine for many applications, and probably what you should choose by default. Larger stripe sizes will lead to reduced contention in high-performance multicore applications, at a trade-off of causing the maximum number of simultaneous resources in use to grow.



data Pool a Source


Show (Pool a) 

data LocalPool a Source

A single striped pool.



:: IO a

Action that creates a new resource.

-> (a -> IO ())

Action that destroys an existing resource.

-> Int

Stripe count. The number of distinct sub-pools to maintain. The smallest acceptable value is 1.

-> NominalDiffTime

Amount of time for which an unused resource is kept open. The smallest acceptable value is 0.5 seconds.

The elapsed time before destroying a resource may be a little longer than requested, as the reaper thread wakes at 1-second intervals.

-> Int

Maximum number of resources to keep open per stripe. The smallest acceptable value is 1.

Requests for resources will block if this limit is reached on a single stripe, even if other stripes have idle resources available.

-> IO (Pool a) 

withResource :: MonadCatchIO m => Pool a -> (a -> m b) -> m bSource

Temporarily take a resource from a Pool, perform an action with it, and return it to the pool afterwards.

  • If the pool has an idle resource available, it is used immediately.
  • Otherwise, if the maximum number of resources has not yet been reached, a new resource is created and used.
  • If the maximum number of resources has been reached, this function blocks until a resource becomes available.

If the action throws an exception of any type, the resource is destroyed, and not returned to the pool.

It probably goes without saying that you should never manually destroy a pooled resource, as doing so will almost certainly cause a subsequent user (who expects the resource to be valid) to throw an exception.

takeResource :: Pool a -> IO (a, LocalPool a)Source

Take a resource from the pool, following the same results as withResource. Note that this function should be used with caution, as improper exception handling can lead to leaked resources.

This function returns both a resource and the LocalPool it came from so that it may either be destroyed (via destroyResource) or returned to the pool (via putResource).

destroyResource :: Pool a -> LocalPool a -> a -> IO ()Source

Destroy a resource. Note that this will ignore any exceptions in the destroy function.

putResource :: LocalPool a -> a -> IO ()Source

Return a resource to the given LocalPool.