-- 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: -- -- -- -- For real-world usage, search the WAI family of packages for -- imports of Control.Reaper. module Control.Reaper -- | Settings for creating a reaper. This type has two parameters: -- workload gives the entire workload, whereas item -- gives an individual piece of the queue. A common approach is to have -- workload be a list of items. This is encouraged by -- defaultReaperSettings and mkListAction. data ReaperSettings workload item -- | Default ReaperSettings value, biased towards having a list of -- work items. defaultReaperSettings :: ReaperSettings [item] item -- | The action to perform on a workload. The result of this is a "workload -- modifying" function. In the common case of using lists, the result -- should be a difference list that prepends the remaining workload to -- the temporary workload. The temporary workload here refers to items -- added to the workload while the reaper action is running. For help -- with setting up such an action, see mkListAction. -- -- Default: do nothing with the workload, and then prepend it to the -- temporary workload. This is incredibly useless; you should definitely -- override this default. reaperAction :: ReaperSettings workload item -> workload -> IO (workload -> workload) -- | Number of microseconds to delay between calls of reaperAction. -- -- Default: 30 seconds. reaperDelay :: ReaperSettings workload item -> Int -- | Add an item onto a workload. -- -- Default: list consing. reaperCons :: ReaperSettings workload item -> item -> workload -> workload -- | Check if a workload is empty, in which case the worker thread will -- shut down. -- -- Default: null. reaperNull :: ReaperSettings workload item -> workload -> Bool -- | An empty workload. -- -- Default: empty list. reaperEmpty :: ReaperSettings workload item -> workload -- | Label of the thread spawned by the reaper. -- -- Default: Reaper. reaperThreadName :: ReaperSettings workload item -> String -- | A data structure to hold reaper APIs. data 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 () -- | Create a reaper addition function. This function can be used to add -- new items to the workload. Spawning of reaper threads will be handled -- for you automatically. mkReaper :: ReaperSettings workload item -> IO (Reaper workload item) -- | A helper function for creating reaperAction functions. You -- would provide this function with a function to process a single work -- item and return either a new work item, or Nothing if the -- work item is expired. mkListAction :: (item -> IO (Maybe item')) -> [item] -> IO ([item'] -> [item'])