Copyright | (c) Dong Han 2017 |
---|---|
License | BSD |
Maintainer | winterland1989@gmail.com |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Z.IO.Resource
Description
This module also implements Gabriel Gonzalez'd idea on Resource
applicative:
http://www.haskellforall.com/2013/06/the-resource-applicative.html. The Applicative
and Monad
instance is
especially useful when you want safely combine multiple resources.
A high performance resource pool is also provided.
Synopsis
- newtype Resource a = Resource {}
- initResource :: IO a -> (a -> IO ()) -> Resource a
- initResource_ :: IO a -> IO () -> Resource a
- withResource :: (MonadMask m, MonadIO m, HasCallStack) => Resource a -> (a -> m b) -> m b
- withResource' :: (MonadMask m, MonadIO m, HasCallStack) => Resource a -> (a -> m () -> m b) -> m b
- data Pool key res
- initPool :: (key -> Resource res) -> Int -> Int -> Resource (Pool key res)
- withPool :: (MonadMask m, MonadIO m, Ord key, HasCallStack) => Pool key res -> key -> (res -> m a) -> m a
- type SimplePool res = Pool () res
- initSimplePool :: Resource res -> Int -> Int -> Resource (SimplePool res)
- withSimplePool :: (MonadMask m, MonadIO m, HasCallStack) => SimplePool res -> (res -> m a) -> m a
- statPool :: Pool key res -> IO (SmallArray (Map key Int))
- liftIO :: MonadIO m => IO a -> m a
Resource management
A Resource
is an IO
action which acquires some resource of type a and
also returns a finalizer of type IO () that releases the resource.
The only safe way to use a Resource
is withResource
and withResource'
,
You should not use the acquire
field directly, unless you want to implement your own
resource management. In the later case, you should mask_
acquire
since
some resource initializations may assume async exceptions are masked.
MonadIO
instance is provided so that you can lift IO
computation inside
Resource
, this is convenient for propagating Resource
around since many
IO
computations carry finalizers.
A convention in Z-IO is that functions returning a Resource
should be
named in initXXX
format, users are strongly recommended to follow this convention.
There're two additional guarantees we made in Z-IO:
- All resources in Z-IO can track its own liveness, throw
ResourceVanished
exception usingthrowECLOSED
orthrowECLOSEDSTM
when used after resource is closed. - All resources' clean up action in Z-IO is idempotent.
Library authors providing initXXX
are also encouraged to provide these guarantees.
initResource :: IO a -> (a -> IO ()) -> Resource a Source #
Create Resource
from create and release action.
Note, resource
doesn't open resource itself, resource is created when you use
with
/ with'
.
withResource :: (MonadMask m, MonadIO m, HasCallStack) => Resource a -> (a -> m b) -> m b Source #
Create a new resource and run some computation, resource is guarantee to be closed.
Be care don't leak the resource through computation return value, because after the computation finishes, the resource is closed already.
withResource' :: (MonadMask m, MonadIO m, HasCallStack) => Resource a -> (a -> m () -> m b) -> m b Source #
Create a new resource and run some computation, resource is guarantee to be closed.
The difference from with
is that the computation will receive an extra
close action, which can be used to close the resource early before the whole
computation finished, the close action can be called multiple times,
only the first call will clean up the resource.
Resource pool
A high performance resource pool.
The Pool is first divided by GHC runtime capabilities, each capability maintains a map from key to living resource list. Resource are fetched from living list first, create on demand if there's no living resource.
Arguments
:: (key -> Resource res) | |
-> Int | maximum number of resources per local pool per key to be maintained. |
-> Int | amount of time after which an unused resource can be released (in seconds). |
-> Resource (Pool key res) |
Initialize a resource pool with given Resource
Like other initXXX functions, this function won't open a resource pool until you use withResource
.
withPool :: (MonadMask m, MonadIO m, Ord key, HasCallStack) => Pool key res -> key -> (res -> m a) -> m a Source #
Open resource inside a given resource pool and do some computation.
This function is thread safe, concurrently usage will be guaranteed to get different resource. If exception happens during computation, resource will be closed(not return to pool).
type SimplePool res = Pool () res Source #
Simple resource pool where lookup via key is not needed.
Arguments
:: Resource res | |
-> Int | maximum number of resources per local pool to be maintained. |
-> Int | amount of time after which an unused resource can be released (in seconds). |
-> Resource (SimplePool res) |
Initialize a SimplePool
.
withSimplePool :: (MonadMask m, MonadIO m, HasCallStack) => SimplePool res -> (res -> m a) -> m a Source #
Open resource with SimplePool
, see withPool