Skip to content

Commit 9229cb7

Browse files
authored
Fix metrics server (parsonsmatt#35)
1 parent c949a60 commit 9229cb7

File tree

2 files changed

+42
-30
lines changed

2 files changed

+42
-30
lines changed

src/Config.hs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
33
{-# LANGUAGE MultiParamTypeClasses #-}
44
{-# LANGUAGE OverloadedStrings #-}
5+
56
{-# OPTIONS_GHC -fno-warn-orphans #-}
7+
68
module Config where
79

10+
import Control.Concurrent (ThreadId)
811
import Control.Exception (throwIO)
912
import Control.Monad.Except (ExceptT, MonadError)
1013
import Control.Monad.IO.Class
@@ -21,10 +24,10 @@ import Database.Persist.Postgresql (ConnectionPool,
2124
ConnectionString,
2225
createPostgresqlPool)
2326
import Network.Wai (Middleware)
27+
import Network.Wai.Handler.Warp (Port)
2428
import Network.Wai.Middleware.RequestLogger (logStdout, logStdoutDev)
2529
import Servant (ServantErr)
2630
import System.Environment (lookupEnv)
27-
import Network.Wai.Handler.Warp (Port)
2831

2932
import Logger
3033

@@ -38,20 +41,23 @@ import Logger
3841
newtype AppT m a
3942
= AppT
4043
{ runApp :: ReaderT Config (ExceptT ServantErr m) a
41-
} deriving ( Functor, Applicative, Monad, MonadReader Config,
42-
MonadError ServantErr, MonadIO)
44+
} deriving
45+
( Functor, Applicative, Monad, MonadReader Config, MonadError ServantErr
46+
, MonadIO
47+
)
4348

4449
type App = AppT IO
4550

4651
-- | The Config for our application is (for now) the 'Environment' we're
4752
-- running in and a Persistent 'ConnectionPool'.
4853
data Config
4954
= Config
50-
{ configPool :: ConnectionPool
51-
, configEnv :: Environment
52-
, configMetrics :: Metrics
53-
, configLogEnv :: LogEnv
54-
, configPort :: Port
55+
{ configPool :: ConnectionPool
56+
, configEnv :: Environment
57+
, configMetrics :: Metrics
58+
, configEkgServer :: ThreadId
59+
, configLogEnv :: LogEnv
60+
, configPort :: Port
5561
}
5662

5763
instance Monad m => MonadMetrics (AppT m) where

src/Init.hs

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@
22

33
module Init where
44

5+
import Control.Concurrent (killThread)
56
import qualified Control.Monad.Metrics as M
67
import Database.Persist.Postgresql (runSqlPool)
8+
import Lens.Micro ((^.))
79
import Network.Wai (Application)
810
import Network.Wai.Metrics (metrics, registerWaiMetrics)
911
import System.Environment (lookupEnv)
10-
import System.Remote.Monitoring (forkServer, serverMetricStore)
12+
import System.Remote.Monitoring (forkServer, serverMetricStore,
13+
serverThreadId)
1114

1215
import Api (app)
1316
import Api.User (generateJavaScript)
1417
import Config (Config (..), Environment (..),
1518
makePool, setLogger)
19+
import Control.Exception (bracket)
20+
import qualified Data.Pool as Pool
21+
import qualified Katip
1622
import Logger (defaultLogEnv)
1723
import Models (doMigrations)
18-
import Safe (readMay)
19-
import Control.Exception (bracket)
2024
import Network.Wai.Handler.Warp (run)
21-
import qualified Data.Pool as Pool
22-
import qualified Katip
25+
import Safe (readMay)
2326

2427
-- | An action that creates a WAI 'Application' together with its resources,
2528
-- runs it, and tears it down on exit
@@ -31,14 +34,12 @@ runApp = bracket acquireConfig shutdownApp runApp
3134
-- | The 'initialize' function accepts the required environment information,
3235
-- initializes the WAI 'Application' and returns it
3336
initialize :: Config -> IO Application
34-
initialize cfg@(Config pool env _ _ _) = do
35-
waiMetrics <-
36-
registerWaiMetrics =<< serverMetricStore
37-
<$> forkServer "localhost" 8000
38-
let logger = setLogger env
39-
runSqlPool doMigrations pool
37+
initialize cfg = do
38+
waiMetrics <- registerWaiMetrics (configMetrics cfg ^. M.metricsStore)
39+
let logger = setLogger (configEnv cfg)
40+
runSqlPool doMigrations (configPool cfg)
4041
generateJavaScript
41-
pure (logger $ metrics waiMetrics $ app cfg)
42+
pure . logger . metrics waiMetrics . app $ cfg
4243

4344
-- | Allocates resources for 'Config'
4445
acquireConfig :: IO Config
@@ -47,23 +48,28 @@ acquireConfig = do
4748
env <- lookupSetting "ENV" Development
4849
logEnv <- defaultLogEnv
4950
pool <- makePool env logEnv
50-
store <- serverMetricStore <$> forkServer "localhost" 8000
51-
waiMetrics <- registerWaiMetrics store
51+
ekgServer <- forkServer "localhost" 8000
52+
let store = serverMetricStore ekgServer
53+
waiMetrics <- registerWaiMetrics store
5254
metr <- M.initializeWith store
53-
pure Config { configPool = pool
54-
, configEnv = env
55-
, configMetrics = metr
56-
, configLogEnv = logEnv
57-
, configPort = port }
55+
pure Config
56+
{ configPool = pool
57+
, configEnv = env
58+
, configMetrics = metr
59+
, configLogEnv = logEnv
60+
, configPort = port
61+
, configEkgServer = serverThreadId ekgServer
62+
}
5863

5964
-- | Takes care of cleaning up 'Config' resources
6065
shutdownApp :: Config -> IO ()
61-
shutdownApp (Config pool _env metr logEnv _port) = do
62-
Katip.closeScribes logEnv
63-
Pool.destroyAllResources pool
66+
shutdownApp cfg = do
67+
Katip.closeScribes (configLogEnv cfg)
68+
Pool.destroyAllResources (configPool cfg)
6469
-- Monad.Metrics does not provide a function to destroy metrics store
6570
-- so, it'll hopefully get torn down when async exception gets thrown
6671
-- at metrics server process
72+
killThread (configEkgServer cfg)
6773
pure ()
6874

6975
-- | Looks up a setting in the environment, with a provided default, and

0 commit comments

Comments
 (0)