-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Build composable components for your application with clear teardown semantics
--   
--   The teardown library allows you to reliably deallocate resources
--   created when initializing your application. It provides:
--   
--   <ul>
--   <li>A ComponentM monad that allows you to build and compose resources
--   with cleanup semantics</li>
--   <li>An API that composes IO cleanup sub-routines safely</li>
--   </ul>
--   
--   Check Control.Teardown.Tutorial for more information.
@package teardown
@version 0.3.0.0


-- | Provides functions that help on the creation of Application teardown
--   sub-routines
module Control.Teardown

-- | A record that <b>is</b> or <b>contains</b> a <a>Teardown</a>
--   sub-routine should instantiate this typeclass
class ITeardown teardown

-- | Executes teardown sub-routine returning a <a>TeardownResult</a>
teardown :: ITeardown teardown => teardown -> IO TeardownResult

-- | A resource or sub-routine that can be transformed into a
--   <a>Teardown</a> operation
class IResource resource
newTeardown :: IResource resource => Text -> resource -> IO Teardown

-- | Sub-routine that performs a resource cleanup operation
data Teardown

-- | Result from a <a>Teardown</a> sub-routine
data TeardownResult

-- | Result is composed by multiple teardown sub-routines
BranchResult :: !Description -> !NominalDiffTime -> !Bool -> ![TeardownResult] -> TeardownResult

-- | Text description of parent teardown spec
[resultDescription] :: TeardownResult -> !Description

-- | Sum of elapsed time on sub-routines execution
[resultElapsedTime] :: TeardownResult -> !NominalDiffTime

-- | Tells if any sub-routines failed
[resultDidFail] :: TeardownResult -> !Bool

-- | Results of inner sub-routines
[resultListing] :: TeardownResult -> ![TeardownResult]

-- | Result represents a single teardown sub-routine
LeafResult :: !Description -> !NominalDiffTime -> !(Maybe SomeException) -> TeardownResult

-- | Text description of parent teardown spec
[resultDescription] :: TeardownResult -> !Description

-- | Sum of elapsed time on sub-routines execution
[resultElapsedTime] :: TeardownResult -> !NominalDiffTime

-- | Exception from sub-routine
[resultError] :: TeardownResult -> !(Maybe SomeException)

-- | Represents a stub cleanup operation (for lifting pure values)
EmptyResult :: !Description -> TeardownResult

-- | Text description of parent teardown spec
[resultDescription] :: TeardownResult -> !Description

-- | Executes teardown sub-routine returning a <a>TeardownResult</a>
teardown :: ITeardown teardown => teardown -> IO TeardownResult

-- | Creates a stub <a>Teardown</a> sub-routine, normally used when a
--   contract expects a teardown return but there is no allocation being
--   made
emptyTeardown :: Description -> Teardown
newTeardown :: IResource resource => Text -> resource -> IO Teardown

-- | Returns a boolean indicating if any of the cleanup sub-routine failed
didTeardownFail :: TeardownResult -> Bool

-- | Returns number of sub-routines that threw an exception on execution of
--   teardown
failedToredownCount :: TeardownResult -> Int

-- | Returns number of sub-routines executed at teardown
toredownCount :: TeardownResult -> Int

-- | Renders an ASCII Tree with the <a>TeardownResult</a> of a
--   <a>Teardown</a> sub-routine execution
renderTeardownReport :: TeardownResult -> Doc


-- | Provides functions that help on the creation of Application teardown
--   sub-routines
module Control.Monad.Component

-- | <a>ComponentM</a> is a wrapper of the <a>IO</a> monad that
--   automatically deals with the composition of <a>Teardown</a>
--   sub-routines from resources allocated in every resource of your
--   application. To build <a>ComponentM</a> actions see the
--   <tt>buildComponent</tt>, <tt>buildComponentWithCleanup</tt> and
--   <tt>buildComponentWithTeardown</tt> functions.
data ComponentM a

-- | Given the name and a <a>ComponentM</a> sub-routine, this function
--   builds an <a>IO</a> sub-routine that returns a <a>Component</a>
--   record.
--   
--   The name argument is used for trace-ability purposes when executing
--   the <a>teardown</a> of a resulting <a>Component</a>.
--   
--   <ul>
--   <li>A note on error scenarios:</li>
--   </ul>
--   
--   Sometimes the given <a>ComponentM</a> sub-routine may fail on
--   execution, in such cases, this function will teardown all component
--   resources allocated so far and throw a <a>ComponentStartupFailure</a>
--   exception.
runComponentM :: Text -> ComponentM a -> IO (Component a)

-- | Represents the result of a <a>ComponentM</a> sub-routine, it contains
--   a resource record which can be recovered using <a>fromComponent</a>
--   and a <a>Teardown</a> sub-routine that can be executed using the
--   <a>teardown</a> function.
data Component a

-- | Fetches the resource of a <a>Component</a> returned by a
--   <a>ComponentM</a> sub-routine.
fromComponent :: Component a -> a
data ComponentError
ComponentFailure :: !Text -> ComponentError
ComponentStartupFailure :: ![SomeException] -> ComponentError

-- | Sub-routine that performs a resource cleanup operation
data Teardown

-- | Result from a <a>Teardown</a> sub-routine
data TeardownResult

-- | Result is composed by multiple teardown sub-routines
BranchResult :: !Description -> !NominalDiffTime -> !Bool -> ![TeardownResult] -> TeardownResult

-- | Text description of parent teardown spec
[resultDescription] :: TeardownResult -> !Description

-- | Sum of elapsed time on sub-routines execution
[resultElapsedTime] :: TeardownResult -> !NominalDiffTime

-- | Tells if any sub-routines failed
[resultDidFail] :: TeardownResult -> !Bool

-- | Results of inner sub-routines
[resultListing] :: TeardownResult -> ![TeardownResult]

-- | Result represents a single teardown sub-routine
LeafResult :: !Description -> !NominalDiffTime -> !(Maybe SomeException) -> TeardownResult

-- | Text description of parent teardown spec
[resultDescription] :: TeardownResult -> !Description

-- | Sum of elapsed time on sub-routines execution
[resultElapsedTime] :: TeardownResult -> !NominalDiffTime

-- | Exception from sub-routine
[resultError] :: TeardownResult -> !(Maybe SomeException)

-- | Represents a stub cleanup operation (for lifting pure values)
EmptyResult :: !Description -> TeardownResult

-- | Text description of parent teardown spec
[resultDescription] :: TeardownResult -> !Description

-- | Executes teardown sub-routine returning a <a>TeardownResult</a>
teardown :: ITeardown teardown => teardown -> IO TeardownResult
newTeardown :: IResource resource => Text -> resource -> IO Teardown

-- | Throw an exception. Note that this throws when this action is run in
--   the monad <tt>m</tt>, not when it is applied. It is a generalization
--   of <a>Control.Exception</a>'s <a>throwIO</a>.
--   
--   Should satisfy the law:
--   
--   <pre>
--   throwM e &gt;&gt; f = throwM e
--   </pre>
throwM :: MonadThrow m => forall e a. Exception e => e -> m a
fail :: MonadFail m => forall a. () => String -> m a

-- | Transforms an <a>IO</a> sub-routine into a <a>ComponentM</a>
--   sub-routine; the given <a>IO</a> sub-routine returns a resource that
--   does not allocate any other resources that would need to be cleaned up
--   on a system shutdown.
buildComponent :: IO a -> ComponentM a

-- | Transforms an <a>IO</a> sub-routine into a <a>ComponentM</a>
--   sub-routine; the given <a>IO</a> sub-routine must return a tuple
--   where:
--   
--   <ul>
--   <li>First position represents the resource being returned from the
--   component</li>
--   <li>Second position represents a named cleanup action that tears down
--   allocated resources to create the first element of the tuple</li>
--   </ul>
buildComponentWithCleanup :: IO (a, (Text, IO ())) -> ComponentM a

-- | Transforms an <a>IO</a> sub-routine into a <a>ComponentM</a>
--   sub-routine; the given <a>IO</a> sub-routine must return a tuple
--   where:
--   
--   <ul>
--   <li>First position represents the resource being returned from the
--   component</li>
--   <li>Second position represents a <a>Teardown</a> record that cleans up
--   allocated resources to create the first element of the tuple</li>
--   </ul>
buildComponentWithTeardown :: IO (a, Teardown) -> ComponentM a


-- | The <i>correct</i> teardown of a system becomes a crucial matter when
--   running applications through GHCi while doing REPL driven development;
--   this library provides a stable API to manage the cleanup process of
--   resources your application allocates when it starts up.
--   
--   One could naively implement a teardown sub-routine of an application
--   by doing something like the following:
--   
--   <pre>
--   -- All functions in this example initialize hypothetical resources, the
--   -- idea stands that there is a way to allocate a system resource
--   -- using some sort of configuration record, and there is a
--   -- sub-routine to release those resources once the application
--   -- shuts down
--   
--   initDb :: Logger -&gt; DbConnInfo -&gt; IO (DbConn, IO ())
--   initDb logger connInfo = do
--     conn &lt;- newConn connInfo
--     return (conn, info logger "Teardown Database" &gt;&gt; closeConn conn)
--   
--   initTcpServer :: Logger -&gt; ServerInfo -&gt; IO (Socket, IO ())
--   initTcpServer logger serverInfo = do
--     socket &lt;- startServer serverInfo
--     return (socket, info logger "Teardown Tcp Server" &gt;&gt; closeSocket socket)
--   
--   initApp :: Logger -&gt; DbConnInfo -&gt; ServerInfo -&gt; IO (IO ())
--   initApp logger connInfo serverInfo = do
--     (connInfo, teardownDb) &lt;- initDb logger connInfo
--     (serverInfo, teardownSocket) &lt;- initTcpServer logger serverInfo
--     -- do something with connInfo and serverInfo ...
--     return (info logger "Teardown Application"
--             &gt;&gt; teardownDb
--             &gt;&gt; teardownSocket)
--   </pre>
--   
--   The previous implementation does not address a few concerns:
--   
--   <ul>
--   <li>If for some reason we execute the <tt>IO ()</tt> sub-routine
--   returned by the <tt>initApp</tt> function more than once, there is
--   likely going to be a runtime exception of the "already closed
--   resource" nature. This library ensures that teardown sub-routines are
--   executed <i>exactly</i> once, even on the scenario where we execute
--   the teardown procedure multiple times.</li>
--   <li>The teardown of sub-systems can be built and composed via the
--   <tt>(&gt;&gt;)</tt> operator, what happens if the <tt>teardownDb</tt>
--   sub-routine in the previous example throws an exception? Likely other
--   resource teardown sub-routines are going to be affected. This library
--   ensures that errors are isolated from every other resource teardown
--   sub-routines.</li>
--   <li>All teardown sub-routines use a description argument to keep track
--   of what is being cleaned up; By requiring this, we avoid confusion
--   around what is going on when shutting down an application. This
--   library makes this documentation a <i>required</i> argument when
--   building teardown sub-routines, thus helping trace-ability.</li>
--   <li>You may notice the structure of teardown sub-routines form a tree
--   shape. This library provides a data structure representation of this
--   tree that allows the developer to report all teardown sub-routines in
--   hierarchy order, with other details around if sub-routines failed (or
--   not).</li>
--   <li>Also, this library keeps track how much time every teardown
--   sub-routine takes, allowing the developer to learn which parts of the
--   teardown procedure are slow and adequately address those on
--   development time (e.g., Faster reload =&gt; Faster development
--   feedback loops).</li>
--   </ul>
--   
--   This tutorial shows some examples on how to use the
--   <tt>Control.Teardown</tt> API and also the rationale behind the
--   typeclasses offered by the library.
module Control.Teardown.Tutorial
