I have the following Scotty app:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Web.Scotty
import Data.Monoid (mconcat)
import Control.Concurrent.STM
import Control.Monad.IO.Class
import Control.Concurrent
main :: IO ()
main = do
counter <- newTVarIO 0
scotty 3000 $
get "/:word" $ do
liftIO $ threadDelay 1000000
liftIO $ atomically $ do
counter' <- readTVar counter
writeTVar counter (counter' + 1)
liftIO $ do
counter' <- atomically (readTVar counter)
print counter'
beam <- param "word"
html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
And am invoking the exposed endpoint like this (200 concurrent requests):
wrk -c 200 -t 20 -d 10 http://127.0.0.1:3000/z
I was expecting the value of the counter'
to be printed sequentially. However, some numbers are missing, and some are duplicated (for example 147
is there twice, but 146
is not there at all).
Two questions:
The only way this can happen I think is that the second
liftIO
is not necessarily followed by the thirdliftIO
. Is this correct? Or is there another explanation for it?How can I print the value of
counter'
in the secondliftIO
? I'm not sure how to place it between (or after)readTVar
andwriteTVar
.