packages feed

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