Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data TimerWheel
- create :: Config -> IO TimerWheel
- destroy :: TimerWheel -> IO ()
- data Config = Config {
- spokes :: !Natural
- resolution :: !(Fixed E6)
- register :: TimerWheel -> IO () -> Fixed E6 -> IO (IO Bool)
- register_ :: TimerWheel -> IO () -> Fixed E6 -> IO ()
- recurring :: TimerWheel -> IO () -> Fixed E6 -> IO (IO ())
- recurring_ :: TimerWheel -> IO () -> Fixed E6 -> IO ()
- data InvalidTimerWheelConfig = InvalidTimerWheelConfig !Config
- newtype TimerWheelDied = TimerWheelDied SomeException
Timer wheel
data TimerWheel Source #
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 at2.5s
will not fire until the timeout thread wakes at3s
.- 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 aTimerWheelDied
exception to the thread thatcreate
d it. If you want to catch exceptions and log them, for example, you will have to bake this into the registered actions yourself.
- There is only one, and it fires expired timers synchronously. If your
timer actions execute quicky,
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 | +-----+-----+-----+-----+-----+-----+-----+-----+
create :: Config -> IO TimerWheel Source #
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
.
destroy :: TimerWheel -> IO () Source #
Tear down a timer wheel by killing the timeout thread.
Instances
Show Config Source # | |
Generic Config Source # | |
type Rep Config Source # | |
Defined in Data.TimerWheel type Rep Config = D1 (MetaData "Config" "Data.TimerWheel" "timer-wheel-0.2.0.1-AciEfOjWRdM4saXj3ReI5W" False) (C1 (MetaCons "Config" PrefixI True) (S1 (MetaSel (Just "spokes") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Natural) :*: S1 (MetaSel (Just "resolution") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (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.
:: TimerWheel | |
-> IO () | Action |
-> Fixed E6 | Delay, in seconds |
-> IO () |
Like register
, but for when you don't intend to cancel the timer.
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.
:: TimerWheel | |
-> IO () | Action |
-> Fixed E6 | Delay, in seconds |
-> IO () |
Like recurring
, but for when you don't intend to cancel the timer.
data InvalidTimerWheelConfig Source #
The timer wheel config was invalid.
spokes
must be positive, and less thanmaxBound
ofInt
.resolution
must be positive.
Instances
Show InvalidTimerWheelConfig Source # | |
Defined in Data.TimerWheel showsPrec :: Int -> InvalidTimerWheelConfig -> ShowS # show :: InvalidTimerWheelConfig -> String # showList :: [InvalidTimerWheelConfig] -> ShowS # | |
Exception InvalidTimerWheelConfig Source # | |
newtype TimerWheelDied Source #
The timeout thread died.
Instances
Show TimerWheelDied Source # | |
Defined in Data.TimerWheel showsPrec :: Int -> TimerWheelDied -> ShowS # show :: TimerWheelDied -> String # showList :: [TimerWheelDied] -> ShowS # | |
Exception TimerWheelDied Source # | |
Defined in Data.TimerWheel |