{-# LANGUAGE Arrows #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
module LiveCoding.Warp
( runWarpC
, runWarpC_
, module X
) where
import Control.Concurrent
import Control.Monad.IO.Class
import Network.HTTP.Types as X
import Network.Wai as X
import Network.Wai.Handler.Warp
import LiveCoding
data WaiHandle = WaiHandle
{ requestVar :: MVar Request
, responseVar :: MVar Response
, appThread :: ThreadId
}
waiHandle :: Port -> Handle IO WaiHandle
waiHandle port = Handle
{ create = do
requestVar <- newEmptyMVar
responseVar <- newEmptyMVar
let app request respond = do
putMVar requestVar request
response <- takeMVar responseVar
respond response
appThread <- forkIO $ run port app
return WaiHandle { .. }
, destroy = \WaiHandle { .. } -> killThread appThread
}
runWarpC
:: Port
-> Cell IO (a, Request) (b, Response)
-> Cell (HandlingStateT IO) a b
runWarpC port cell = proc a -> do
WaiHandle { .. } <- handling $ waiHandle port -< ()
request <- arrM $ liftIO . takeMVar -< requestVar
(b, response) <- liftCell cell -< (a, request)
arrM $ liftIO . uncurry putMVar -< (responseVar, response)
returnA -< b
runWarpC_
:: Port
-> Cell IO Request Response
-> Cell (HandlingStateT IO) () ()
runWarpC_ port cell = runWarpC port $ arr snd >>> cell >>> arr ((), )