{-# LANGUAGE TypeFamilies, UndecidableInstances #-}modulePrioritySync.Internal.Schedule(Schedule(..))whereimportPrioritySync.Internal.UserDataimportPrioritySync.Internal.RoomimportPrioritySync.Internal.QueueimportPrioritySync.Internal.ClaimContextimportPrioritySync.Internal.RoomGroupimportControl.Concurrent.STMimportControl.MonadimportData.List-- | Schedule a task to run from a prioritized 'Queue'. The task will wait until it arrives at (or, with failover, near) the top of queue. Typical usage:---- > Schedule q 2 room1---- Only the rooms inside the 'Schedule' declaration are claimed with scheduling. If access to a room doesn't need to be prioritized, it can be set outside-- the schedule:---- > (Schedule q 2 room1,room2)--dataSchedulepc=Schedule(Queuep)pctypeinstanceUserData(Schedulepc)=UserDatacinstance(RoomGroupc)=>RoomGroup(Schedulepc)whereroomsOf(Schedule__c)=roomsOfcinstance(Ordp,RoomGroupc,ClaimContextc,ClaimHandlec~())=>ClaimContext(Schedulepc)wheretypeClaimHandle(Schedulepc)=Maybe(TaskHandlep)approveClaimsEntering=scheduleClaimsapproveClaimsEnteringapproveClaimsExiting=scheduleClaimsapproveClaimsExitingwaitingAction(Schedule__c)Nothing=waitingActionc()waitingAction(Schedule__c)(Justtask)=flipunlessretry.or=<<mapM(\m->m>>returnTrue`orElse`returnFalse)[pullFromToptask>>return(),waitingActionc()]scheduleClaims::(Ordp,RoomGroupc,ClaimContextc,ClaimHandlec~())=>(c->[Claim(UserDatac)]->STM())->Schedulepc->[Claim(UserDatac)]->STM(Maybe(TaskHandlep))scheduleClaimsapproveClaimsX(Schedule__c)cs|null(intersect(mapclaimedRoomcs)$roomsOfc)=approveClaimsXccs>>returnNothingscheduleClaimsapproveClaimsX(Scheduleqpc)cs=liftMJust$putTaskqp(approveClaimsXccs)