module Simulation.Aivika.Processor.RoundRobbin
(roundRobbinProcessor,
roundRobbinProcessorUsingIds) where
import Control.Monad
import Simulation.Aivika.Simulation
import Simulation.Aivika.Event
import Simulation.Aivika.Process
import Simulation.Aivika.Processor
import Simulation.Aivika.Stream
import Simulation.Aivika.Queue.Infinite.Base
roundRobbinProcessor :: Processor (Process Double, Process a) a
roundRobbinProcessor =
Processor $
runProcessor roundRobbinProcessorUsingIds . mapStreamM f where
f (timeout, p) =
let x = do timeout' <- timeout
pid <- liftSimulation newProcessId
return (timeout', pid)
in return (x, p)
roundRobbinProcessorUsingIds :: Processor (Process (Double, ProcessId), Process a) a
roundRobbinProcessorUsingIds =
Processor $ \xs ->
Cons $
do q <- liftSimulation newFCFSQueue
let process =
do t@(x, p) <- dequeue q
(timeout, pid) <- x
result <- timeoutProcessUsingId timeout pid p
case result of
Just a -> return a
Nothing ->
do liftEvent $ enqueue q t
process
processor =
bufferProcessor
(consumeStream $ liftEvent . enqueue q)
(repeatProcess process)
runStream $ runProcessor processor xs