Skip to content

Instantly share code, notes, and snippets.

@CodyReichert
Last active August 29, 2015 14:08

Revisions

  1. CodyReichert revised this gist Nov 29, 2014. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions DevelMain.hs
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,11 @@
    -- | Development version to be run inside GHCi.
    -- Development version to be run inside GHCi.
    --
    -- Modified DevelMain.hs to reload Chrome browser tabs on recompile
    --
    -- start this up with:
    --
    -- cabal repl --ghc-options="-O0 -fobject-code"
    --o
    -- run with:
    --
    -- run with:
    -- :l DevelMain
    -- DevelMain.update
    --
  2. CodyReichert created this gist Nov 6, 2014.
    75 changes: 75 additions & 0 deletions DevelMain.hs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    -- | Development version to be run inside GHCi.
    --
    -- Modified DevelMain.hs to reload Chrome browser tabs on recompile
    --
    -- start this up with:
    --
    -- cabal repl --ghc-options="-O0 -fobject-code"
    --o
    -- run with:
    --
    -- :l DevelMain
    -- DevelMain.update
    --
    -- You will need to add these packages to your .cabal file
    -- * foreign-store >= 0.1 (very light-weight)
    -- * warp (you already depend on this, it just isn't in your .cabal file)
    --
    -- If you don't use cabal repl, you will need
    -- to add settings to your .ghci file.
    --
    -- :set -DDEVELOPMENT
    --
    -- There is more information about using ghci
    -- on the wiki: https://github.com/yesodweb/yesod/wiki/ghci

    module DevelMain where

    import Application (getApplicationDev)

    import Control.Exception (finally)
    import Control.Concurrent
    import Data.IORef
    import Foreign.Store
    import Network.Wai.Handler.Warp
    import Prelude
    import System.Process

    -- | Start or restart the server.
    -- A Store holds onto some data across ghci reloads
    update :: IO ()
    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 ->
    -- shut the server down with killThread and wait for the done signal
    modifyStoredIORef tidStore $ \tid -> do
    killThread tid
    withStore doneStore takeMVar >> readStore doneStore >>= start
    rawSystem "chromix" ["with", "localhost:3000", "reloadWithoutCache"]
    return ()

    where
    doneStore = Store 0
    tidStoreNum = 1

    modifyStoredIORef :: Store (IORef a) -> (a -> IO a) -> IO ()
    modifyStoredIORef store f = withStore store $ \ref -> do
    v <- readIORef ref
    f v >>= writeIORef ref

    -- | Start the server in a separate thread.
    start :: MVar () -- ^ Written to when the thread is killed.
    -> IO ThreadId
    start done = do
    (port,app) <- getApplicationDev
    forkIO $ system "chromix-server" >> return ()
    forkIO (finally (runSettings (setPort port defaultSettings) app)
    (putMVar done ()))