-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | A timer wheel
--
-- This library provides a timer wheel data structure for
--
--
-- - O(1) registering IO actions to fire after a given
-- amount of time
-- - O(1) canceling registered actions
--
--
-- It is similar to TimerManager from GHC.Event, but can
-- scale much better under concurrent access patterns.
--
-- An unreleased version of this library has a backpack-based
-- signature for selecting from a variety of different data structures
-- used internally. However, until backpack has broader support
-- on Hackage, and in Haddocks, etc, I decided to just hard-code
-- something decent (a priority search queue). This makes the
-- O(1) claims above a bit of a lie, as these rely on using a
-- linked list data structure internally.
@package timer-wheel
@version 0.2.0.1
module Data.TimerWheel
-- | A TimerWheel is a vector-of-collections-of timers to fire. It
-- is configured with a spoke count and resolution. Timers
-- may be scheduled arbitrarily far in the future. A timeout thread is
-- spawned to step through the timer wheel and fire expired timers at
-- regular intervals.
--
--
-- - The spoke count determines the size of the timer
-- vector.
- A larger spoke count will result in less
-- insert contention at each spoke and will require more
-- memory to store the timer wheel.
- A smaller spoke
-- count will result in more insert contention at each spoke
-- and will require less memory to store the timer
-- wheel.
-- - The resolution determines both the duration of time that
-- each spoke corresponds to, and how often the timeout thread wakes. For
-- example, with a resolution of 1s, a timer that expires
-- at 2.5s will not fire until the timeout thread wakes
-- at 3s.
- A larger resolution will result
-- in more insert contention at each spoke, less accurate
-- timers, and will require fewer wakeups by the timeout
-- thread.
- A smaller resolution will result in less
-- insert contention at each spoke, more accurate timers, and
-- will require more wakeups by the timeout thread.
-- - The timeout thread has some important properties:
- There is
-- only one, and it fires expired timers synchronously. If your timer
-- actions execute quicky, register them directly. Otherwise,
-- consider registering an action that enqueues the real action to
-- be performed on a job queue.
- Synchronous exceptions thrown by
-- enqueued IO actions will bring the thread down, which will
-- cause it to asynchronously throw a TimerWheelDied exception to
-- the thread that created it. If you want to catch exceptions and
-- log them, for example, you will have to bake this into the registered
-- actions yourself.
--
--
-- Below is a depiction of a timer wheel with 6 timers inserted
-- across 8 spokes, and a resolution of 0.1s.
--
--
-- 0s .1s .2s .3s .4s .5s .6s .7s .8s
-- +-----+-----+-----+-----+-----+-----+-----+-----+
-- | | A | | B,C | D | | | E,F |
-- +-----+-----+-----+-----+-----+-----+-----+-----+
--
data TimerWheel
-- | Create a timer wheel.
--
-- Throws. If the config is invalid, throws
-- InvalidTimerWheelConfig.
--
-- Throws. If the timeout thread dies, asynchronously throws
-- TimerWheelDied to the thread that called create.
create :: Config -> IO TimerWheel
-- | Tear down a timer wheel by killing the timeout thread.
destroy :: TimerWheel -> IO ()
data Config
Config :: !Natural -> !Fixed E6 -> Config
-- | Spoke count.
[spokes] :: Config -> !Natural
-- | Resolution, in seconds.
[resolution] :: Config -> !Fixed E6
-- | register wheel action delay registers an action
-- action in timer wheel wheel to fire
-- after delay seconds.
--
-- Returns an action that, when called, attempts to cancel the timer, and
-- returns whether or not it was successful (False means the
-- timer has already fired).
--
-- Subsequent calls to the cancel action have no effect, and continue to
-- return whatever the first result was.
register :: TimerWheel -> IO () -> Fixed E6 -> IO (IO Bool)
-- | Like register, but for when you don't intend to cancel the
-- timer.
register_ :: TimerWheel -> IO () -> Fixed E6 -> IO ()
-- | recurring wheel action delay registers an action
-- action in timer wheel wheel to fire
-- every delay seconds.
--
-- Returns an action that, when called, cancels the recurring timer.
recurring :: TimerWheel -> IO () -> Fixed E6 -> IO (IO ())
-- | Like recurring, but for when you don't intend to cancel the
-- timer.
recurring_ :: TimerWheel -> IO () -> Fixed E6 -> IO ()
-- | The timer wheel config was invalid.
--
--
-- - spokes must be positive, and less than maxBound
-- of Int.
-- - resolution must be positive.
--
data InvalidTimerWheelConfig
InvalidTimerWheelConfig :: !Config -> InvalidTimerWheelConfig
-- | The timeout thread died.
newtype TimerWheelDied
TimerWheelDied :: SomeException -> TimerWheelDied
instance GHC.Show.Show Data.TimerWheel.InvalidTimerWheelConfig
instance GHC.Show.Show Data.TimerWheel.TimerWheelDied
instance GHC.Show.Show Data.TimerWheel.Config
instance GHC.Generics.Generic Data.TimerWheel.Config
instance GHC.Exception.Type.Exception Data.TimerWheel.InvalidTimerWheelConfig
instance GHC.Exception.Type.Exception Data.TimerWheel.TimerWheelDied