!      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ NonePSX schedule%Type abstracting a mutable reference.1This can be thought of as a mutable version of a Lens' (PrimState m) s' with the lens functor specialised to (,) a for each a.  None7M schedule%Handle generator. Runtime invariants: A handle from one generator is not used in a context that expects a handle from a different generator. TODO: use a string or other data to distinguish the contexts.MNewly generated handles are distinguishable from previously-generated ones.  is used to check this.scheduleCheck that an existing handle is consistent with the current state of a handle generator, i.e. it must not be part of the generator's future.  None7P)*schedule4Check the map 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 handles you obtain via a similarly non-standard method, including by deserialisation of a parent data structure, you must run + map handle. means the check passed;  errmsg gives a failure reason.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.+scheduleCheck that an existing handle is consistent with the current state of the structure, i.e. it is not a handle that could be generated in the future.0scheduleAppend an item on a key, returning a handle to remove it with. The same item may be added twice, in which case it will occupy multiple positions in the map, and the handles distinguish these occurences.1scheduleRDelete an item corresponding to a given handle. If the item was already removed,  is returned instead.2scheduleJRemove an item from a key, from the front. Return Nothing if key is empty. !"'()*+,-./012 !")('*+,-./012None"#7_8schedule)The state of all scheduled pending tasks.t is the type of task-params.>schedule,The current status of a task as returned by L.?scheduleBThe task is not pending - either it was already run, or cancelled.@schedule+The task is due to run at some future tick.AscheduleThe task is running right now.Bschedule3A task that is currently or was part of a schedule.tF is the type of input parameter for each task, i.e. the task contents.Gschedule9Check 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 Bzs you obtain via a similarly non-standard method, including by deserialisation of a parent data structure, you must run H schedule task. means the check passed;  errmsg gives a failure reason.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.HscheduleCheck 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.Ischedule7Get 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.Jschedule8Get the previous tick, whose tasks have all already run.Kschedule6Get the number of ticks until the next scheduled task.QThis may be used by an impure runtime environment to set an actual timeout; see  Control.Clock for a starting point.Mschedule5Schedule a task to run after a given number of ticks.This is relative to I; a 0r 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.:1data TPar = TPar !(Task TPar) deriving (Show, Eq)s = newScheduleDlet (t, s') = after 1 (TPar t) s -- @t@ on LHS & RHS, tying the knott)Task (Delete 1 (RHandle {getHandle = 0}))taskStatus t sTaskNotPendingtaskStatus t s'@TaskPending 1 (TPar (Task (Delete 1 (RHandle {getHandle = 0})))))taskStatus t s' == TaskPending 1 (TPar t)TrueNscheduleACancel a task. Result is Nothing if task was not already pending.Oschedule%Cancel a task, discarding the result.PscheduleGReschedule a pending task to instead run after a given number of ticks.If the task was not already pending, do nothing. If you need to reschedule a task unconditionally even if it was already cancelled or run, use both O and M in combination.QscheduleoPop the next task to be run in this tick. If there are no more tasks remaining, then advance to the next tick.Rschedule3Lock the schedule before running a particular task.This prevents popOrTick from being called, or other tasks from running. It is not re-entrant; only one task is supposed to run at once.Sschedule4Unlock the schedule after running a particular task.This allows popOrTick to be called again and other tasks to run. It is not re-entrant; only one task is supposed to run at once.89=<;:>A@?BCDEFGHIJKLMNOPQRSEDBC>A@?89=<;:FGHIJKLMNOPQRSNoneP_h]bschedule?Run an action, accumulating its monoid result until it returns Nothing.TODO: export to upstream extracscheduleAConvert a modification function into a state transition function.dschedule;Convert a getter function into a state transition function.escheduleBConvert a state transition function into a state transition arrow.fschedule;Convert a modification arrow into a state transition arrow.gschedule8Convert a getter function into a state transition arrow.8>?@ABDEFGHIJKLMNOPbcdefgEDB>?@A8FGHIJKLMNOPbcdefgNone "#7PSX_tischeduleSExpects waiting on usjscheduleResult of the Future|schedule1SFutures we're waiting for, with our own timeout.TNote that the SFuture might have its own separate timeout which is different; this t) timeout is when *we* stop waiting on it.For example if (i ~ TimedResult a)4 and our timeout is longer than their timeout then } will get a GotResult (TimedOut t).}scheduleSFutures that have completed, with the result. This is meant to be a holding place and the caller of this should move items from here into some other place to indicate that the results have been processed, so that if it is called twice it does not process these results twice.hjikmlnoz{}|~onkmlhji~z{}|NoneSXscheduleSee ! for details on what this is for.scheduleAA maybe-impure supplier of time, to a pure scheduled computation. The type cC is the computational context where clock operations occur, e.g. a  such as .Clock implementations must be monotonic. See System.Time.MonotonicD for an example on how to wrap non-monotonic clocks to be monotonic.scheduleGet the current time.schedule<Suspend the current computation for a given number of ticks.SNothing else in the computation runs until the suspension is over. Afterwards, , will give the expected value, i.e. for all n: fdo old <- clockNow clockDelay n new <- clockNow let new' = assert (old + n <= new) newThe relation is  not , because the computer might have slept during the mean time or something. On the other hand, if the underlying physical clock might delay for a shorter period than requested, then implementations of this function must loop-delay until the  condition is satisfied.The above is the only condition that scheduled computations should rely on, and any actual physical real delay is up to the implementation.scheduleInterleave actions with ticks.This is typically recommended for the use-case where your action represents a stream of inputs, e.g. from the network or the user. It is meant to satisfy the same functionality as the selectR system call found in common operating systems, used with a timeout parameter.If actionR when executed repeatedly gives a sequence of results, then in the expression  clkAct <-  clock action, a subsequent call to  clkActw when executed repeatedly gives the same sequence of results but with ticks interleaved in between them. Executing  clkAct: closes any resources and invalidates any future calls to clkAct.It is not necessary to call  if any part of  (e.g. child threads) throws an exception - implementations should detect these situations and clean these up automatically. This frees the user of this function from having to add extra constraints which would be the case if it had been necessary to run   ... (finClocked clkAct) as cleanup.schedule'Given an action, run it with a timeout.This is typically recommended for the use-case where your action represents the response to a single previously-sent request.The action may complete despite the timeout firing, in which case its result will be lost. This is in general unavoidable and is a common property that one simply has to live with in distributed systems. If you run the input action repeatedly, then this property applies *for every execution*, i.e. it is possible that you get 10 timeouts even though the action succeeded 10 times, and you'll lose 10 results.,If you want all results of all actions, use  clockWith} instead. The downside with that, is that it's slightly less efficient than this, as it will interleave every single EJ event and it is up to you to deal with skipping/ignoring any of them.scheduleRun  then . DE DENoneSX_hschedule/Create a new clock ticking at a given interval.schedule>Create a new clock ticking at a given interval in picoseconds.schedule?Create a new clock ticking at a given interval in milliseconds.schedule,Create a new clock ticking at 1 millisecond.schedule'Create a new clock ticking at 1 second.schedule Check for a non-negative number.scheduleCheck for a positive number.schedule Convert a System.Time.Monotonic.Clock into an abstract ? for scheduled computations, ticking at the given interval.DE NoneSX_scheduleSomething that can run 8 state transition functions.This could be pure (e.g.  ") or impure (e.g. reference to a ). Examples:  primState :: PrimMonad m => RunSched t (ReaderT (PrimST m (Schedule t)) m) primState sched = asks statePrimST >>= run -> lift (run sched) state :: Monad m => RunSched t (StateT (Schedule t) m) zoom _lens . state :: Monad m => RunSched t (StateT s m) %See the unit tests for more examples.scheduleA more general version of  that uses a  -like optic.Given an inner computation  it -> m a where one branch of the it type has a (E, t)Q tuple representing individual input tasks, return an outer computation of type i -> m a where the i type only has a E-. When the outer computation receives these E? inputs, it automatically resolves the relevant tasks of type t that are active for that EF, and passes each tuple in sequence to the wrapped inner computation.8>?@ABDEFGHIJKLMNOPbcdefg NonePSXhscheduleSomething that can run 8 state transition arrows.This could be pure (e.g. ") or impure (e.g. reference to a ).scheduleA more general version of  that uses a  -like optic.Given an inner computation a it o where one branch of the it type has a (E, t)Q tuple representing individual input tasks, return an outer computation of type a i o where the i type only has a E-. When the outer computation receives these E? inputs, it automatically resolves the relevant tasks of type t that are active for that EF, and passes each tuple in sequence to the wrapped inner computation.8>?@ABDEFGHIJKLMNOPbcdefg !"#$%&'()*+,-./01223456789:;<"=>?@ABCDEFGHIIJKLMNOPQRRSTU<VWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   'schedule-0.2.0.0-K49JMtE71hY4NI1zeQoVl3Control.Monad.Primitive.ExtraData.Rsv.CommonData.Rsv.RMMapData.Schedule.Internal Data.ScheduleControl.Schedule.Future Control.ClockControl.Clock.IOControl.Monad.ScheduleControl.Arrow.ScheduleControl.Exceptionfinally Control.Monad.Trans.State.StrictStateTPrimSTControl.Lens.PrismPrismControl.Arrow.Transformer.State StateArrow(primitive-0.7.0.0-9xMM76CsovTEGnXCHiCdRJControl.Monad.Primitive PrimState PrimMonad statePrimST readPrimST writePrimST modifyPrimSTstMutVarRHandleRHandles getNextHandle newHandles nextHandle checkHandle withHandlesEnqueuesUnqueuesDequeue $fShowRHandle $fReadRHandle$fGenericRHandle $fEqRHandle $fOrdRHandle $fEnumRHandle$fBoundedRHandle$fShowRHandles$fReadRHandles$fGenericRHandles $fEqRHandlesRMMaphandlescontent $fShowRMMap $fReadRMMap$fGenericRMMap $fEqRMMapDelete_content_handles checkValidityemptyisEmpty!toListenqueueunqueuedequeue $fShowDelete $fReadDelete$fGenericDelete $fEqDelete $fOrdDeleteSchedulenowtaskspendingrunning TaskStatusTaskNotPending TaskPending TaskRunningTask TickDeltaTick newSchedule checkTasktickNowtickPrev ticksToIdle taskStatusaftercancelcancel_renew popOrTick acquireTask releaseTask $fShowTask $fReadTask $fGenericTask$fEqTask $fOrdTask$fShowTaskStatus$fReadTaskStatus$fGenericTaskStatus$fEqTaskStatus$fOrdTaskStatus$fShowSchedule$fReadSchedule$fGenericSchedule $fEqSchedule whileJustMmodSTgetSTstAimodAgetASFuture SFWaitingSFResult TimedResultTimedOut GotResultOMapOSet$fShowTimedResult$fReadTimedResult$fGenericTimedResult$fEqTimedResult$fOrdTimedResult $fShowSFuture $fReadSFuture$fGenericSFuture $fEqSFuture $fOrdSFutureSExpect seExpects seResults _SFWaiting _SFResult $fShowSExpect $fReadSExpect$fGenericSExpect $fEqSExpect $fOrdSExpectSFErrorSFEAlreadyFinishedSFEInvalidPrecondition sfePreExpect sfePreActual SFStatusFullSFStatus Expecting NotExpecting _seExpects _seResults sCheckStatus sExpectFuture sExpectCancelsExpectTimeout sFutureResult$fMonoidSExpect$fSemigroupSExpect$fShowSFStatus$fReadSFStatus$fGenericSFStatus $fEqSFStatus $fOrdSFStatus $fShowSFError $fReadSFError$fGenericSFError $fEqSFError $fOrdSFErrorClocked runClocked finClockedClockclockNow clockDelay clockWith clockTimer clockTicknewClock newClockPico newClockMilli newClock1ms newClock1s convClock clockWithIO clockTimerIO voidInputRunSchedrunTick runTicksTogetInputmkOutputtickTaskbase GHC.MaybeNothingJustGHC.BaseMonadghc-prim GHC.TypesIO GHC.Classes<=== checkNonNegcheckPos