-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | A parallel producer/consumer engine (thread pool)
--
-- A parallel producer/consumer engine (thread pool). There are lots of
-- features in the Engine, to include dynamically adjustable hooks,
-- managed state, and injection points.
@package Control-Engine
@version 0.0.1
module Control.ThreadPool
-- | A trival thread pool for pure functions (mappings). Simply specify the
-- number of threads desired and a mutator function.
threadPool :: Int -> (a -> b) -> IO (Chan a, Chan b)
-- | A trivial thread pool that allows IO mutator functions. Evaluation of
-- output is not strict - force evaluation if desired!
threadPoolIO :: Int -> (a -> IO b) -> IO (Chan a, Chan b)
-- | Implemented here is a thread pool library on crack. - - 1.0
-- Introduction - Typically, a thread pool is a set of execution contexts
-- that will execute - tasks from an input queue. Typically, thread pools
-- are used to parallize - the processing of incoming work across all
-- available CPUs without going - through the expense of starting a new
-- thread for every new task. - - In Control.Engine you will
-- find a somewhat unique implementation. The - Engine is not only
-- a set of threads running a common mutator on the input - queue,
-- producing an output queue, but also include hooks, task injection, and
-- - state management. - - Hooks :: (a -> IO Maybe a) - Hooks can be
-- added and removed during execution without creating a new - engine.
-- They allow the developer to modify tasks: - * prior to parallization
-- (for sequential preprocessing) - * in parallel, prior to main mutation
-- funciton - * in parallel, after mutation function - * post
-- parallization (for sequential post processing) - - State Management -
-- The stateManager waits for any updates to the mutator state or hooks.
-- If any - modifications are made then the new set of hooks (or state)
-- is provided - to the workers. This allows the state of the entire
-- engine to be atomically - modified (it is all STM) but allows the
-- workers to use cheap and quick - MVars. - - The thinking here is that
-- changing the hooks and state is a rare / low contention action while
-- the need for this information will be constant - and performance
-- critical. - - Injection - One injection point allows injection of a
-- result that had no preceding - task. With another
-- the initial hooks (Input hooks) can be bypassed.
module Control.Engine
-- | If all you want is a basic thread pool, this will work. You should
-- consider using Control.ThreadPool instead.
--
-- Evaluation of the result is forced using seq.
initSimpleEngine :: Int -> (job -> result) -> IO (Chan job, Chan result)
-- | Simpler than calling initEngine, but it allows no state or
-- interaction with the hooks and injectors. No strictness is forced.
initSimpleEngineIO :: Int -> (job -> IO result) -> IO (Chan job, Chan result)
-- | To initilize an engine you must provide: * the number of threads * an
-- action that will get the input * an action that will consume output *
-- a mutator function to perform on all inputs * an initial state for the
-- mutator function
--
-- No strictness is forced - be sure you force evaluation if wanted. All
-- hooks start out empty.
initEngine :: (Eq st) => Int -> (IO job) -> (result -> IO ()) -> (st -> job -> IO (Maybe result)) -> st -> IO (Engine job result st)
-- | An Engine represents a pool of threads ready to execute tasks.
data Engine job result state
Eng :: Chan job -> Chan result -> TVar [Hook state job] -> TVar [Hook state job] -> TVar [Hook state result] -> TVar [Hook state result] -> MVar [Hook state job] -> MVar [Hook state job] -> MVar [Hook state result] -> MVar [Hook state result] -> TVar state -> Engine job result state
chan1 :: Engine job result state -> Chan job
chan2 :: Engine job result state -> Chan result
tvInHook :: Engine job result state -> TVar [Hook state job]
tvPreMutateHook :: Engine job result state -> TVar [Hook state job]
tvPostMutateHook :: Engine job result state -> TVar [Hook state result]
tvOutHook :: Engine job result state -> TVar [Hook state result]
mvInHook :: Engine job result state -> MVar [Hook state job]
mvPreMutateHook :: Engine job result state -> MVar [Hook state job]
mvPostMutateHook :: Engine job result state -> MVar [Hook state result]
mvOutHook :: Engine job result state -> MVar [Hook state result]
state :: Engine job result state -> TVar state
data Hook st msg
Hk :: (st -> msg -> IO (Maybe msg)) -> Int -> String -> Hook st msg
hkFunc :: Hook st msg -> st -> msg -> IO (Maybe msg)
hkPriority :: Hook st msg -> Int
hkDescription :: Hook st msg -> String
data HookLoc
InputHook :: HookLoc
PreMutateHook :: HookLoc
PostMutateHook :: HookLoc
OutputHook :: HookLoc
addInputHook :: Engine job result state -> Hook state job -> IO ()
addOutputHook :: Engine job result state -> Hook state result -> IO ()
addPreMutateHook :: Engine job result state -> Hook state job -> IO ()
addPostMutateHook :: Engine job result state -> Hook state result -> IO ()
delInputHook :: Engine j r s -> String -> IO ()
delOutputHook :: Engine j r s -> String -> IO ()
delPreMutateHook :: Engine j r s -> String -> IO ()
delPostMutateHook :: Engine j r s -> String -> IO ()
-- | Allows adding tasks that bypass the input hooks.
injectPreMutator :: Engine j r s -> j -> IO ()
-- | Allows bypassing the mutator, meaning a result can be
-- produced without a task. This still hits the output hooks.
injectPostMutator :: Engine j r s -> r -> IO ()
instance Eq HookLoc
instance Ord HookLoc
instance Show HookLoc
instance Show (Hook a s)
instance Ord (Hook a s)
instance Eq (Hook m s)