MVar
MVar
makes it easy to share mutable state among different IO
actions. This is handy in Scotty, which uses ActionT Text IO
for request/response handling.
Let's use MVar
to make a couple of endpoints: one that
suspends, waiting for an MVar
to be set,
and another to set
it.
{-# LANGUAGE OverloadedStrings #-}
import qualified Control.Concurrent.MVar as MVar
import qualified Control.Monad.Trans.Class as Class
import qualified Data.Text.Lazy as TL
import qualified Web.Scotty as Scotty
main :: IO ()
= do
main <- MVar.newEmptyMVar
sem 3000 $ do
Scotty.scotty "/suspend" $ do
Scotty.get <- Class.lift $ MVar.takeMVar sem
key $ TL.pack $
Scotty.text concat [
"Resumed with \""
, (TL.unpack key)"\"."
,
]"/resume/:key" $ do
Scotty.get <- Scotty.param "key"
key $ MVar.putMVar sem key
Class.lift $ TL.pack $
Scotty.text concat [
"Resuming with \""
, (TL.unpack key)"\"."
, ]
This requires a few dependencies from Hackage:
build-depends: base, scotty, transformers, text
We can run the server with cabal:
$ cabal run
Preprocessing executable 'scotty-suspend' for scotty-suspend-0.1.0.0...
Running scotty-suspend...
Setting phasers to stun... (port 3000) (ctrl-c to quit)
Now we can make a couple of requests that get suspended until later:
$ curl localhost:3000/suspend
(this hangs until the first /resume/:key is requested)
Resumed with "foo".
$ curl localhost:3000/suspend
(this hangs until the next /resume/:key is requested)
Resumed with "bar".
Finally we can resume the suspended requests with a couple more:
$ curl localhost:3000/resume/foo
Resuming with "foo".
$ curl localhost:3000/resume/bar
Resuming with "bar".