graninas / Hydra

Hydra is a full-fledged framework for building web services, multithreaded and concurrent applications with SQL and KV DB support.
BSD 3-Clause "New" or "Revised" License
184 stars 13 forks source link

ChurchM meteor-counter-app hangs unexpectedly #1

Closed graninas closed 4 years ago

graninas commented 5 years ago

ChurchM meteor-counter-app hangs at random time.

meteor_counter.cfg:

Config
  { useLog = True
  , method = ChurchM
  , appConfig = AppConfig
      { enableDelays = False
      , maxMeteors = Just 1000000
      , logDiscovered = False
      , logTracked    = False
      , logTotal      = True
      }
  }

stack exec meteor-counter-app

schernichkin commented 5 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, она может откатывать любую транзакцию до бесконечности, что тут и происходит.

graninas commented 4 years ago

This happened due to some laziness issues.

Fixed.