Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module is intended to be imported qualified:
import TimerWheel (TimerWheel) import TimerWheel qualified
Synopsis
- data TimerWheel
- data Config = Config {
- spokes :: !Int
- resolution :: !Seconds
- type Seconds = Fixed E9
- data Timer a
- create :: Scope -> Config -> IO TimerWheel
- with :: Config -> (TimerWheel -> IO a) -> IO a
- count :: TimerWheel -> IO Int
- register :: TimerWheel -> Seconds -> IO () -> IO (Timer Bool)
- register_ :: TimerWheel -> Seconds -> IO () -> IO ()
- recurring :: TimerWheel -> Seconds -> IO () -> IO (Timer ())
- recurring_ :: TimerWheel -> Seconds -> IO () -> IO ()
- cancel :: Timer a -> IO a
Timer wheel
data TimerWheel Source #
A timer wheel is a vector-of-collections-of timers to fire. Timers may be one-shot or recurring, and may be scheduled arbitrarily far in the future.
A timer wheel is configured with a spoke count and resolution:
The spoke count determines the size of the timer vector.
A larger spoke count will require more memory, but will result in less insert contention.
The resolution determines the duration of time that each spoke corresponds to, and thus how often timers are checked for expiry.
For example, in a timer wheel with a resolution of
1 second
, a timer that is scheduled to fire at8.4 o'clock
will end up firing around9.0 o'clock
instead (that is, on the1 second
-boundary).A larger resolution will result in more insert contention and less accurate timers, but will require fewer 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, you can
register
them directly. Otherwise, consider registering an action that enqueues the real action to be performed on a job queue. - A synchronous exception thrown by a registered timer will bring the timeout thread down, and the exception will be propagated to the thread that created the timer wheel. If you want to log and ignore exceptions, for example, you will have to bake this into the registered actions yourself.
API summary
Create | Query | Modify |
---|---|---|
create | count | register |
with | register_ | |
recurring | ||
recurring_ |
Timer wheel configuration
A timer wheel config.
spokes
must be ∈[1, maxBound]
, and is set to1024
if invalid.resolution
must be ∈(0, ∞]
, and is set to1
if invalid.
API summary
Create |
---|
Config |
Config | |
|
Instances
Generic Config Source # | |
Show Config Source # | |
type Rep Config Source # | |
Defined in TimerWheel type Rep Config = D1 ('MetaData "Config" "TimerWheel" "timer-wheel-1.0.0-inplace" 'False) (C1 ('MetaCons "Config" 'PrefixI 'True) (S1 ('MetaSel ('Just "spokes") 'SourceUnpack 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Just "resolution") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Seconds))) |
type Seconds = Fixed E9 Source #
A number of seconds, with nanosecond precision.
You can use numeric literals to construct a value of this type, e.g. 0.5
.
Otherwise, to convert from a type like Int
or Double
, you can use the generic numeric conversion function
realToFrac
.
Timer
Constructing a timer wheel
Querying a timer wheel
Registering timers in a timer wheel
:: TimerWheel | The timer wheel |
-> Seconds | The delay before the action is fired |
-> IO () | The action to fire |
-> IO (Timer Bool) | The timer |
register wheel delay action
registers action
in wheel
to fire after delay
seconds.
When canceled, the timer returns whether or not the cancelation was successful; False
means the timer had either
already fired, or had already been canceled.
:: TimerWheel | The timer wheel |
-> Seconds | The delay before the action is fired |
-> IO () | The action to fire |
-> IO () |
Like register
, but for when you don't intend to cancel the timer.
:: TimerWheel | The timer wheel |
-> Seconds | The delay before each action is fired |
-> IO () | The action to fire repeatedly |
-> IO (Timer ()) | The timer |
recurring wheel action delay
registers action
in wheel
to fire in delay
seconds, and every
delay
seconds thereafter.
:: TimerWheel | |
-> Seconds | The delay before each action is fired |
-> IO () | The action to fire repeatedly |
-> IO () |
Like recurring
, but for when you don't intend to cancel the timer.