odd-jobs-0.2.0: dev/DevelMain.hs
{-# LANGUAGE OverloadedStrings #-}
-- | Running your app inside GHCi.
--
-- > stack ghci
--
-- To start your app, run:
--
-- > :l DevelMain
-- > DevelMain.update
--
-- You can also call @DevelMain.shutdown@ to stop the app
--
-- There is more information about this approach,
-- on the wiki: https://github.com/yesodweb/yesod/wiki/ghci
module DevelMain where
import Prelude
import Control.Concurrent (MVar, ThreadId, forkIO, killThread,
newEmptyMVar, putMVar, takeMVar)
import Control.Exception (finally)
import Control.Monad ((>=>))
import Data.IORef (IORef, newIORef, readIORef,
writeIORef)
import Foreign.Store (Store (..), lookupStore, readStore,
storeAction, withStore)
import GHC.Word (Word32)
import Network.Wai.Handler.Warp (defaultSettings, runSettings,
setPort)
-- import OddJobs.Endpoints (startApp, stopApp)
-- import qualified ElmCodeGen
-- | Start or restart the server.
-- newStore is from foreign-store.
-- A Store holds onto some data across ghci reloads
update :: IO ()
update = undefined
-- update = do
-- mtidStore <- lookupStore tidStoreNum
-- case mtidStore of
-- -- no server running
-- Nothing -> do
-- done <- storeAction doneStore newEmptyMVar
-- tid <- start done
-- _ <- storeAction (Store tidStoreNum) (newIORef tid)
-- return ()
-- -- server is already running
-- Just tidStore -> restartAppInNewThread tidStore
-- where
-- doneStore :: Store (MVar ())
-- doneStore = Store 0
-- -- shut the server down with killThread and wait for the done signal
-- restartAppInNewThread :: Store (IORef ThreadId) -> IO ()
-- restartAppInNewThread tidStore = modifyStoredIORef tidStore $ \tid -> do
-- killThread tid
-- withStore doneStore takeMVar
-- readStore doneStore >>= start
-- -- | Start the server in a separate thread.
-- start :: MVar () -- ^ Written to when the thread is killed.
-- -> IO ThreadId
-- start done = do
-- -- (port, config, app) <- initialize
-- -- ElmCodeGen.updatea
-- forkIO (finally startApp
-- -- Note that this implies concurrency
-- -- between shutdownApp and the next app that is starting.
-- -- Normally this should be fine
-- (putMVar done () >> stopApp))
-- | kill the server
shutdown :: IO ()
shutdown = do
mtidStore <- lookupStore tidStoreNum
case mtidStore of
-- no server running
Nothing -> putStrLn "no app running"
Just tidStore -> do
withStore tidStore $ readIORef >=> killThread
putStrLn "App is shutdown"
tidStoreNum :: Word32
tidStoreNum = 1
modifyStoredIORef :: Store (IORef a) -> (a -> IO a) -> IO ()
modifyStoredIORef store f = withStore store $ \ref -> do
v <- readIORef ref
f v >>= writeIORef ref
main :: IO ()
main = update