Search code examples
haskellconcurrencyhappstack

How to exit from Hackstack Server App?


I'm creating a Happstack server application, but I don't know how to end the application .

If I have:

main = do
  printf "begin server"
  simpleHTTP nullConf myHomepage
  printf "end server"

I can run it ok, and I can kill the application (linux) with CTRL+C, but the last print is never executed. How can I exit gracefully from Happstack? It bothers me because I notice that eventlog is not generated if I don't exit correctly from the application.

UPDATE:

The application is using Dyre at the top main.


Solution

  • I generally use forkIO to spawn simpleHTTP in a separate thread. And then waitForTermination to wait for ^C.

    module Main where
    
    import Control.Concurrent (killThread, forkIO)
    import Happstack.Server (nullConf, simpleHTTP, ok, toResponse)
    import Happstack.State (waitForTermination)
    
    main :: IO ()
    main =
        do putStrLn "begin server"
           httpThreadId <- forkIO $ simpleHTTP nullConf (ok $ toResponse "This site rules!")
           waitForTermination
           killThread httpThreadId
           putStrLn "end server"
    

    waitForTermination comes from the happstack-state package. It really needs to be moved somewhere else for multiple reasons. If you don't want to install happstack-state you can copy and paste a local copy into your app:

    -- | Wait for a signal.
    --   On unix, a signal is sigINT or sigTERM. 
    waitForTermination :: IO ()
    waitForTermination
        = do istty <- queryTerminal stdInput
             mv <- newEmptyMVar
             installHandler softwareTermination (CatchOnce (putMVar mv ())) Nothing
             case istty of
               True  -> do installHandler keyboardSignal (CatchOnce (putMVar mv ())) Nothing
                           return ()
               False -> return ()
             takeMVar mv