Safe Haskell | None |
---|---|
Language | Haskell2010 |
Data.Schedule
Description
Data structure representing scheduled tasks.
Most of the time you will want the more fully-featured Control.Monad.Schedule or Control.Arrow.Schedule modules instead, which re-export this module.
Synopsis
- type Tick = Integer
- type TickDelta = Word64
- data Task t
- data TaskStatus t
- = TaskNotPending
- | TaskPending !Tick !t
- | TaskRunning !t
- data Schedule t
- newSchedule :: Schedule t
- checkValidity :: Schedule t -> Maybe Text
- checkTask :: Schedule t -> Task t -> Bool
- tickNow :: Schedule t -> Tick
- tickPrev :: Schedule t -> Tick
- ticksToIdle :: Schedule t -> Maybe TickDelta
- taskStatus :: HasCallStack => Task t -> Schedule t -> TaskStatus t
- after :: TickDelta -> t -> Schedule t -> (Task t, Schedule t)
- cancel :: Task t -> Schedule t -> (Maybe t, Schedule t)
- cancel_ :: Task t -> Schedule t -> ((), Schedule t)
- renew :: TickDelta -> Task t -> Schedule t -> (Maybe (Task t), Schedule t)
- whileJustM :: (Monad m, Monoid a) => m (Maybe a) -> m a
- modST :: (s -> s) -> s -> ((), s)
- getST :: (s -> o) -> s -> (o, s)
- stA :: (s -> os) -> (i, s) -> os
- imodA :: (i -> s -> s) -> (i, s) -> ((), s)
- getA :: (s -> a) -> (i, s) -> (a, s)
Documentation
A task that is currently or was part of a schedule.
t
is the type of input parameter for each task, i.e. the task contents.
data TaskStatus t Source #
The current status of a task as returned by taskStatus
.
Constructors
TaskNotPending | The task is not pending - either it was already run, or cancelled. |
TaskPending !Tick !t | The task is due to run at some future tick. |
TaskRunning !t | The task is running right now. |
Instances
The state of all scheduled pending tasks.
t
is the type of task-params.
Instances
Eq t => Eq (Schedule t) Source # | |
Read t => Read (Schedule t) Source # | |
Show t => Show (Schedule t) Source # | |
Generic (Schedule t) Source # | |
type Rep (Schedule t) Source # | |
Defined in Data.Schedule.Internal type Rep (Schedule t) = D1 (MetaData "Schedule" "Data.Schedule.Internal" "schedule-0.3.0.0-rXAR2JhUGJ487cqZKqedA" False) (C1 (MetaCons "Schedule" PrefixI True) ((S1 (MetaSel (Just "now") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Tick) :*: S1 (MetaSel (Just "tasks") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (RMMap Tick t))) :*: (S1 (MetaSel (Just "pending") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Set (Task t))) :*: S1 (MetaSel (Just "running") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Maybe (Task t, t)))))) |
newSchedule :: Schedule t Source #
checkValidity :: Schedule t -> Maybe Text Source #
Check the schedule that its internal invariants all hold.
You must run this on every instance obtained not via the API functions here.
For example, you must run this on instances obtained via deserialisation,
which in general cannot check the complex invariants maintained by the API
functions. Also, for all Task
s you obtain via a similarly non-standard
method, including by deserialisation of a parent data structure, you must
run
.checkTask
schedule task
Nothing
means the check passed;
gives a failure reason.Just
errmsg
Note: this does not guard against all malicious behaviour, but it does guard against violation (either malicious or accidental) of the runtime invariants assumed by this data structure.
checkTask :: Schedule t -> Task t -> Bool Source #
Check that an existing task is consistent with the current state of the structure, i.e. it is not a task that could be generated in the future.
tickNow :: Schedule t -> Tick Source #
Get the current tick, whose tasks have not all run yet.
From the perspective of the pure computation that is running this schedule, you should treat this as the current "logical time", even if an impure clock is telling you that the "environment time" is in the future.
ticksToIdle :: Schedule t -> Maybe TickDelta Source #
Get the number of ticks until the next scheduled task.
This may be used by an impure runtime environment to set an actual timeout; see Control.Clock for a starting point.
taskStatus :: HasCallStack => Task t -> Schedule t -> TaskStatus t Source #
after :: TickDelta -> t -> Schedule t -> (Task t, Schedule t) Source #
Schedule a task to run after a given number of ticks.
This is relative to tickNow
; a 0
delta schedules the task to be run at
the end of the current tick, i.e. as soon as possible but not immediately.
If your task params needs to refer to the task itself, you may achieve this by using the standard Haskell "tying the knot" technique, e.g.:
>>>
data TPar = TPar !(Task TPar) deriving (Show, Eq)
>>>
s = newSchedule
>>>
let (t, s') = after 1 (TPar t) s -- @t@ on LHS & RHS, tying the knot
>>>
t
Task (Delete 1 (RHandle {getHandle = 0}))>>>
taskStatus t s
TaskNotPending>>>
taskStatus t s'
TaskPending 1 (TPar (Task (Delete 1 (RHandle {getHandle = 0}))))>>>
taskStatus t s' == TaskPending 1 (TPar t)
True
cancel :: Task t -> Schedule t -> (Maybe t, Schedule t) Source #
Cancel a task. Result is Nothing if task was not already pending.
Other general utilities
General monad / state-transition utils to be exported to another library
whileJustM :: (Monad m, Monoid a) => m (Maybe a) -> m a Source #
Run an action, accumulating its monoid result until it returns Nothing
.
TODO: export to upstream extra
modST :: (s -> s) -> s -> ((), s) Source #
Convert a modification function into a state transition function.
getST :: (s -> o) -> s -> (o, s) Source #
Convert a getter function into a state transition function.
stA :: (s -> os) -> (i, s) -> os Source #
Convert a state transition function into a state transition arrow.