Closed graninas closed 4 years ago
Это происходит из-за reader starvation. Если добавить:
publishMeteor :: AppState -> Meteor -> L.LangL Int
publishMeteor st meteor = L.atomically $ do
L.modifyVar (_channel st) $ Set.insert meteor
length <$> L.readVar (_channel st)
meteorShower :: AppState -> Region -> L.LangL ()
meteorShower st region = go 0
where
go c = do
meteor <- L.evalRandom $ getRandomMeteor region
when (doLogDiscovered st) $ L.logInfo $ "New meteor discovered: " <> show meteor
cnt <- publishMeteor st meteor
if (c == 1000)
then L.logInfo $ "Yet another 1000 meteors published. Channel len = " <> (show cnt) <> "."
else go (c + 1)
то будет видно, что данные в очередь продолжают добавляться, но reader ничего не может считать, т.к. у него постоянно происходит откат. Здесь надо использовать не STM, а очередь с back pressure. Или MVar в крайнем случае, он хотя бы fairness гарантирует (хотя не застрахует от бесконечного роста очереди, если writer-ы работают быстрее reader-ов).
З.Ы. Reader starvation - не reader starvation:), они там все и читают и пишут. Я просто хотел сказать, что meteorShower продолжает генерировать данные, а meteorCounter постоянно уходит в rollback. В итоге до обновления totalMeteors программа так и не доходит. Из-за этого кажется, что она "зависает", но это даже не livelock, это просто логика работы такая. STM в Хаскеле не гарантирует fairness, она может откатывать любую транзакцию до бесконечности, что тут и происходит.
This happened due to some laziness issues.
Fixed.
ChurchM meteor-counter-app hangs at random time.
meteor_counter.cfg
:stack exec meteor-counter-app