Open DISTEL100 opened 1 month ago
Thanks for finding this! I can sort of reproduce, but I'm getting a different (yet still incorrect) scheduling:
ghci> runScheduleIO $ flow $ (f300 +@+ f500) @>-^ arrM (liftIO . print)
Left 300
Right 500
Left 600
Left 900
Left 1200
Right 1000
Left 1500
Left 1800
Left 2100
Right 1500
Left 2400
Right 2000
Left 2700
Left 3000
^CInterrupted.
I have an inkling that this might be an upstream issue in https://github.com/turion/monad-schedule. Let me investigate.
The problem is not related to the clock structures, since it can be reproduced with automata:
ghci> a300 = Data.Automaton.constM (wait 300 >> pure 300) >>> accumulateWith (+) 0
ghci> a500 = Data.Automaton.constM (wait 500 >> pure 500) >>> accumulateWith (+) 0
ghci> runScheduleIO $ Data.Automaton.reactimate $ schedulePair a300 a500 >>> arrM (liftIO . print)
300
500
600
900
1200
1000
1500
1800
1500
2100
2400
2000
2700
3000
^CInterrupted.
Which versions of rhine
and monad-schedule
are you using? (I'm using rhine-1.4.0.1
and monad-schedule-0.2
)
i have rhine ==1.4.0.1 and monad-schedule 0.2.0.1 and i just ran it again and had the same output like you
Thanks for finding this! I can sort of reproduce, but I'm getting a different (yet still incorrect) scheduling:
ghci> runScheduleIO $ flow $ (f300 +@+ f500) @>-^ arrM (liftIO . print) Left 300 Right 500 Left 600 Left 900 Left 1200 Right 1000 Left 1500 Left 1800 Left 2100 Right 1500 Left 2400 Right 2000 Left 2700 Left 3000 ^CInterrupted.
Yes, it unfortunately depends on how fast the GHC IO machine is running. Basically, if there is an IO delay that is too big then an action may fail to even start before the other finishes. In that case, the second one cannot judge whether it should have waited for the first one.
I don't have a good solution for this other than deprecating the MonadSchedule IO
instance. I'll have to think about this. For the time being, your workaround should be replacing runScheduleIO
by runFreeAsync . runScheduleIO
everywhere.
ok, thanks for the fast replies!
I'm afraid this is a known and poorly documented issue in monad-schedule
. A workaround would be using https://hackage.haskell.org/package/monad-schedule-0.2.0.1/docs/Control-Monad-Schedule-FreeAsync.html.
For example:
ghci> runFreeAsync $ runScheduleIO $ Data.Automaton.reactimate $ scheduleList (a300 :| [a500]) >>> arrM (liftIO . print)
300 :| []
500 :| []
600 :| []
900 :| []
1000 :| []
1200 :| []
1500 :| [1500]
The issue is that the MonadSchedule IO
instance is not very well behaved.
Hah I was mistaken luckily. There is a rare race condition in schedulePair
when two clocks are supposed to tick at exactly the same time. I'll publish a fix later.
I had hoped that #343 had fixed this. @DISTEL100 What ghc version are you on? Can you clone the rhine
repository and run cabal test all
?
i am using ghc 9.4.8 and the tests are all passing
There seems to be a problem with the parallel clock when composing two pure clocks in
ScheduleT
. The merged output is not ordered by the timestamps.The following is a minimal example to reproduce the issue:
The output is:
I would expect it to be