-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Efficiently run periodic, on-demand actions -- -- API docs and the README are available at -- http://www.stackage.org/package/auto-update. @package auto-update @version 0.2.4 -- | In a multithreaded environment, running actions on a regularly -- scheduled background thread can dramatically improve performance. For -- example, web servers need to return the current time with each HTTP -- response. For a high-volume server, it's much faster for a dedicated -- thread to run every second, and write the current time to a shared -- IORef, than it is for each request to make its own call to -- getCurrentTime. -- -- But for a low-volume server, whose request frequency is less than once -- per second, that approach will result in more calls to -- getCurrentTime than necessary, and worse, kills idle GC. -- -- This library solves that problem by allowing you to define actions -- which will either be performed by a dedicated thread, or, in times of -- low volume, will be executed by the calling thread. -- -- Example usage: -- --
-- import Data.Time
-- import Control.AutoUpdate
--
-- getTime <- mkAutoUpdate defaultUpdateSettings
-- { updateAction = getCurrentTime
-- , updateFreq = 1000000 -- The default frequency, once per second
-- }
-- currentTime <- getTime
--
--
-- For more examples, see the blog post introducing this library.
module Control.AutoUpdate
-- | Settings to control how values are updated.
--
-- This should be constructed using defaultUpdateSettings and
-- record update syntax, e.g.:
--
--
-- let settings = defaultUpdateSettings { updateAction = getCurrentTime }
--
data UpdateSettings a
-- | Default value for creating an UpdateSettings.
defaultUpdateSettings :: UpdateSettings ()
-- | Action to be performed to get the current value.
--
-- Default: does nothing.
updateAction :: UpdateSettings a -> IO a
-- | Microseconds between update calls. Same considerations as
-- threadDelay apply.
--
-- Default: 1 second (1000000)
updateFreq :: UpdateSettings a -> Int
-- | NOTE: This value no longer has any effect, since worker threads are
-- dedicated instead of spawned on demand.
--
-- Previously, this determined how many times the data must be requested
-- before we decide to spawn a dedicated thread.
--
-- Default: 3
updateSpawnThreshold :: UpdateSettings a -> Int
-- | Label of the thread being forked.
--
-- Default: AutoUpdate
updateThreadName :: UpdateSettings a -> String
-- | Generate an action which will either read from an automatically
-- updated value, or run the update action in the current thread.
mkAutoUpdate :: UpdateSettings a -> IO (IO a)
-- | Generate an action which will either read from an automatically
-- updated value, or run the update action in the current thread if the
-- first time or the provided modify action after that.
mkAutoUpdateWithModify :: UpdateSettings a -> (a -> IO a) -> IO (IO a)
-- | Unstable API which exposes internals for testing.
module Control.Debounce.Internal
-- | Settings to control how debouncing should work.
--
-- This should be constructed using defaultDebounceSettings and
-- record update syntax, e.g.:
--
--
-- let settings = defaultDebounceSettings { debounceAction = flushLog }
--
data DebounceSettings
DebounceSettings :: Int -> IO () -> DebounceEdge -> String -> DebounceSettings
-- | Length of the debounce timeout period in microseconds.
--
-- Default: 1 second (1000000)
[debounceFreq] :: DebounceSettings -> Int
-- | Action to be performed.
--
-- Note: all exceptions thrown by this action will be silently discarded.
--
-- Default: does nothing.
[debounceAction] :: DebounceSettings -> IO ()
-- | Whether to perform the action on the leading edge or trailing edge of
-- the timeout.
--
-- Default: leadingEdge.
[debounceEdge] :: DebounceSettings -> DebounceEdge
-- | Label of the thread spawned when debouncing.
--
-- Default: Debounce.
[debounceThreadName] :: DebounceSettings -> String
-- | Setting to control whether the action happens at the leading and/or
-- trailing edge of the timeout.
data DebounceEdge
-- | Perform the action immediately, and then begin a cooldown period. If
-- the trigger happens again during the cooldown, wait until the end of
-- the cooldown and then perform the action again, then enter a new
-- cooldown period.
Leading :: DebounceEdge
-- | Perform the action immediately, and then begin a cooldown period. If
-- the trigger happens again during the cooldown, it is ignored.
LeadingMute :: DebounceEdge
-- | Start a cooldown period and perform the action when the period ends.
-- If another trigger happens during the cooldown, it has no effect.
Trailing :: DebounceEdge
-- | Start a cooldown period and perform the action when the period ends.
-- If another trigger happens during the cooldown, it restarts the
-- cooldown again.
TrailingDelay :: DebounceEdge
-- | Perform the action immediately, and then begin a cooldown period. If
-- the trigger happens again during the cooldown, wait until the end of
-- the cooldown and then perform the action again, then enter a new
-- cooldown period.
--
-- Example of how this style debounce works:
--
-- -- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ....... ....... ....... -- X X X X --leadingEdge :: DebounceEdge -- | Perform the action immediately, and then begin a cooldown period. If -- the trigger happens again during the cooldown, it is ignored. -- -- Example of how this style debounce works: -- --
-- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ....... -- X X --leadingMuteEdge :: DebounceEdge -- | Start a cooldown period and perform the action when the period ends. -- If another trigger happens during the cooldown, it has no effect. -- -- Example of how this style debounce works: -- --
-- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ....... -- X X --trailingEdge :: DebounceEdge -- | Start a cooldown period and perform the action when the period ends. -- If another trigger happens during the cooldown, it restarts the -- cooldown again. -- -- N.B. If a trigger happens DURING the debounceAction it -- starts a new cooldown. So if the debounceAction takes -- longer than the debounceFreq, it might run again before -- the previous action has ended. -- -- Example of how this style debounce works: -- --
-- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ............... -- X X --trailingDelayEdge :: DebounceEdge mkDebounceInternal :: MVar () -> (Int -> IO ()) -> DebounceSettings -> IO (IO ()) instance GHC.Classes.Eq Control.Debounce.Internal.DebounceEdge instance GHC.Show.Show Control.Debounce.Internal.DebounceEdge -- | Debounce an action, ensuring it doesn't occur more than once for a -- given period of time. -- -- This is useful as an optimization, for example to ensure that logs are -- only flushed to disk at most once per second. -- -- Example usage: -- --
-- > printString <- mkDebounce defaultDebounceSettings
-- { debounceAction = putStrLn "Running action"
-- , debounceFreq = 5000000 -- 5 seconds
-- , debounceEdge = trailingEdge -- Trigger on the trailing edge
-- }
-- > printString
-- Running action
-- > printString
-- <Wait five seconds>
-- Running action
--
--
-- See the fast-logger package (System.Log.FastLogger) for
-- real-world usage.
module Control.Debounce
-- | Generate an action which will trigger the debounced action to be
-- performed.
--
-- N.B. The generated action will always immediately return,
-- regardless of the debounceFreq, as the debounced
-- action (and the delay/cooldown) is always performed in a separate
-- thread.
mkDebounce :: DebounceSettings -> IO (IO ())
-- | Settings to control how debouncing should work.
--
-- This should be constructed using defaultDebounceSettings and
-- record update syntax, e.g.:
--
--
-- let settings = defaultDebounceSettings { debounceAction = flushLog }
--
data DebounceSettings
-- | Default value for creating a DebounceSettings.
defaultDebounceSettings :: DebounceSettings
-- | Length of the debounce timeout period in microseconds.
--
-- Default: 1 second (1000000)
debounceFreq :: DebounceSettings -> Int
-- | Action to be performed.
--
-- Note: all exceptions thrown by this action will be silently discarded.
--
-- Default: does nothing.
debounceAction :: DebounceSettings -> IO ()
-- | Whether to perform the action on the leading edge or trailing edge of
-- the timeout.
--
-- Default: leadingEdge.
debounceEdge :: DebounceSettings -> DebounceEdge
-- | Label of the thread spawned when debouncing.
--
-- Default: Debounce.
debounceThreadName :: DebounceSettings -> String
-- | Perform the action immediately, and then begin a cooldown period. If
-- the trigger happens again during the cooldown, wait until the end of
-- the cooldown and then perform the action again, then enter a new
-- cooldown period.
--
-- Example of how this style debounce works:
--
-- -- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ....... ....... ....... -- X X X X --leadingEdge :: DebounceEdge -- | Perform the action immediately, and then begin a cooldown period. If -- the trigger happens again during the cooldown, it is ignored. -- -- Example of how this style debounce works: -- --
-- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ....... -- X X --leadingMuteEdge :: DebounceEdge -- | Start a cooldown period and perform the action when the period ends. -- If another trigger happens during the cooldown, it has no effect. -- -- Example of how this style debounce works: -- --
-- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ....... -- X X --trailingEdge :: DebounceEdge -- | Start a cooldown period and perform the action when the period ends. -- If another trigger happens during the cooldown, it restarts the -- cooldown again. -- -- N.B. If a trigger happens DURING the debounceAction it -- starts a new cooldown. So if the debounceAction takes -- longer than the debounceFreq, it might run again before -- the previous action has ended. -- -- Example of how this style debounce works: -- --
-- ! = function execution -- . = cooldown period -- X = debounced code execution -- -- ! ! ! ! -- ....... ............... -- X X --trailingDelayEdge :: DebounceEdge module Control.Reaper.Internal -- | A data structure to hold reaper APIs. data Reaper workload item Reaper :: (item -> IO ()) -> IO workload -> ((workload -> workload) -> IO workload) -> IO workload -> IO () -> Reaper workload item -- | Adding an item to the workload [reaperAdd] :: Reaper workload item -> item -> IO () -- | Reading workload. [reaperRead] :: Reaper workload item -> IO workload -- | Modify the workload. The resulting workload is returned. -- -- If there is no reaper thread, the modifier will not be applied and -- reaperEmpty will be returned. -- -- If the reaper is currently executing jobs, those jobs will not be in -- the given workload and the workload might appear empty. -- -- If all jobs are removed by the modifier, the reaper thread will not be -- killed. The reaper thread will only terminate if reaperKill is -- called or the result of reaperAction satisfies -- reaperNull. [reaperModify] :: Reaper workload item -> (workload -> workload) -> IO workload -- | Stopping the reaper thread if exists. The current workload is -- returned. [reaperStop] :: Reaper workload item -> IO workload -- | Killing the reaper thread immediately if exists. [reaperKill] :: Reaper workload item -> IO () -- | This module provides the ability to create reapers: dedicated cleanup -- threads. These threads will automatically spawn and die based on the -- presence of a workload to process on. Example uses include: -- --