Base.hs.template 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. -- vim: ft=haskell
  2. {-# LANGUAGE RecordWildCards #-}
  3. {-# LANGUAGE OverloadedStrings #-}
  4. module $module_path$.Base where
  5. import Control.Concurrent.STM
  6. (atomically,TQueue,writeTQueue,STM,retry,TVar,newTVar)
  7. import Snap.Core (Snap,route)
  8. import qualified Snap.Http.Server as HTTP
  9. import Snap.Util.FileServe (serveDirectory)
  10. data Config = Config { cfgPort :: !Int
  11. -- ^ The port to run on
  12. , cfgStaticDir :: Maybe FilePath
  13. -- ^ Content to be served off of the root, relative to
  14. -- the directory that the server was started in
  15. } deriving (Show)
  16. -- | A default @Config@ value that will produce a server that runs on port 8080,
  17. -- and serves no static content.
  18. defaultConfig :: Config
  19. defaultConfig = Config { cfgPort = 8080, cfgStaticDir = Nothing }
  20. -- | Spawn a snap server, and run the given RPC action.
  21. runServer :: Config -> Snap () -> IO ()
  22. runServer Config { .. } serveRpc =
  23. do let snapCfg :: HTTP.Config Snap ()
  24. snapCfg = HTTP.setPort cfgPort HTTP.defaultConfig
  25. HTTP.simpleHttpServe snapCfg body
  26. where
  27. body =
  28. do serveRpc
  29. case cfgStaticDir of
  30. Just path -> route [ ("", serveDirectory path) ]
  31. Nothing -> return ()
  32. data Request req resp = ReadRequest req (resp -> IO ())
  33. | WriteRequest req
  34. -- Sample Variables ------------------------------------------------------------
  35. -- | A TVar that blocks when it's empty, but allows writes even when it's full.
  36. newtype SampleTVar a = SampleVar (TVar (Maybe a))
  37. newTSampleVar :: STM (TSampleTVar a)
  38. newTSampleVar = TSampleVar `fmap` newTVar Nothing
  39. newTSampleVarIO :: IO (TSampleTVar a)
  40. newTSampleVarIO = atomically (TSampleVar `fmap` newTVar Nothing)
  41. writeTSampleVar :: SampleVar a -> a -> STM ()
  42. writeTSampleVar (TSampleVar tv) a = writeTVar tv (Just a)
  43. readTSampleVar :: TSampleVar a -> STM ()
  44. readTSampleVar (TSampleVar tv) =
  45. do mb <- readTVar tv
  46. case mb of
  47. Just a -> return a
  48. Nothing -> retry