Skip to content

Commit 39f2515

Browse files
authored
Merge pull request #61 from diogob/refactor-modules
Refactor modules and export full stand-alone server from library
2 parents 2d6a835 + 1168c58 commit 39f2515

File tree

14 files changed

+464
-335
lines changed

14 files changed

+464
-335
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# - https://circleci.com/docs/2.0/language-haskell/
33
# - https://circleci.com/blog/publishing-to-github-releases-via-circleci/
44
#
5-
version: 2
5+
version: 2.1
66
jobs:
77
publish:
88
docker:

app/Config.hs

Lines changed: 0 additions & 65 deletions
This file was deleted.

app/Main.hs

Lines changed: 5 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,9 @@
11
module Main where
22

3-
import Protolude hiding (replace)
4-
import PostgresWebsockets
5-
import Config (AppConfig (..),
6-
PgVersion (..),
7-
minimumPgVersion,
8-
prettyVersion,
9-
readOptions)
3+
import Protolude
4+
import PostgresWebsockets
105

11-
import qualified Data.ByteString as BS
12-
import qualified Data.ByteString.Base64 as B64
13-
import Data.String (IsString (..))
14-
import Data.Text (pack, replace, strip, stripPrefix)
15-
import Data.Text.Encoding (encodeUtf8, decodeUtf8)
16-
import qualified Hasql.Statement as H
17-
import qualified Hasql.Session as H
18-
import qualified Hasql.Decoders as HD
19-
import qualified Hasql.Encoders as HE
20-
import qualified Hasql.Pool as P
21-
import Network.Wai.Application.Static
22-
import Data.Time.Clock (UTCTime, getCurrentTime)
23-
import Control.AutoUpdate ( defaultUpdateSettings
24-
, mkAutoUpdate
25-
, updateAction
26-
)
27-
28-
import Network.Wai (Application, responseLBS)
29-
import Network.HTTP.Types (status200)
30-
import Network.Wai.Handler.Warp
31-
import Network.Wai.Middleware.RequestLogger (logStdout)
32-
import System.IO (BufferMode (..),
33-
hSetBuffering)
34-
35-
isServerVersionSupported :: H.Session Bool
36-
isServerVersionSupported = do
37-
ver <- H.statement () pgVersion
38-
return $ ver >= pgvNum minimumPgVersion
39-
where
40-
pgVersion =
41-
H.Statement "SELECT current_setting('server_version_num')::integer"
42-
HE.noParams (HD.singleRow $ HD.column $ HD.nonNullable HD.int4) False
6+
import System.IO (BufferMode (..), hSetBuffering)
437

448
main :: IO ()
459
main = do
@@ -51,67 +15,5 @@ main = do
5115
<> prettyVersion
5216
<> " / Connects websockets to PostgreSQL asynchronous notifications."
5317

54-
conf <- loadSecretFile =<< readOptions
55-
shutdownSignal <- newEmptyMVar
56-
let host = configHost conf
57-
port = configPort conf
58-
listenChannel = toS $ configListenChannel conf
59-
pgSettings = toS (configDatabase conf)
60-
waitForShutdown cl = void $ forkIO (takeMVar shutdownSignal >> cl >> die "Shutting server down...")
61-
62-
appSettings = setHost ((fromString . toS) host)
63-
. setPort port
64-
. setServerName (toS $ "postgres-websockets/" <> prettyVersion)
65-
. setTimeout 3600
66-
. setInstallShutdownHandler waitForShutdown
67-
. setGracefulShutdownTimeout (Just 5)
68-
$ defaultSettings
69-
70-
putStrLn $ ("Listening on port " :: Text) <> show (configPort conf)
71-
72-
let shutdown = putErrLn ("Broadcaster connection is dead" :: Text) >> putMVar shutdownSignal ()
73-
pool <- P.acquire (configPool conf, 10, pgSettings)
74-
multi <- newHasqlBroadcaster shutdown listenChannel pgSettings
75-
getTime <- mkGetTime
76-
77-
runSettings appSettings $
78-
postgresWsMiddleware getTime listenChannel (configJwtSecret conf) pool multi $
79-
logStdout $ maybe dummyApp staticApp' (configPath conf)
80-
81-
where
82-
mkGetTime :: IO (IO UTCTime)
83-
mkGetTime = mkAutoUpdate defaultUpdateSettings {updateAction = getCurrentTime}
84-
staticApp' :: Text -> Application
85-
staticApp' = staticApp . defaultFileServerSettings . toS
86-
dummyApp :: Application
87-
dummyApp _ respond =
88-
respond $ responseLBS status200 [("Content-Type", "text/plain")] "Hello, Web!"
89-
90-
loadSecretFile :: AppConfig -> IO AppConfig
91-
loadSecretFile conf = extractAndTransform secret
92-
where
93-
secret = decodeUtf8 $ configJwtSecret conf
94-
isB64 = configJwtSecretIsBase64 conf
95-
96-
extractAndTransform :: Text -> IO AppConfig
97-
extractAndTransform s =
98-
fmap setSecret $ transformString isB64 =<<
99-
case stripPrefix "@" s of
100-
Nothing -> return . encodeUtf8 $ s
101-
Just filename -> chomp <$> BS.readFile (toS filename)
102-
where
103-
chomp bs = fromMaybe bs (BS.stripSuffix "\n" bs)
104-
105-
-- Turns the Base64url encoded JWT into Base64
106-
transformString :: Bool -> ByteString -> IO ByteString
107-
transformString False t = return t
108-
transformString True t =
109-
case B64.decode $ encodeUtf8 $ strip $ replaceUrlChars $ decodeUtf8 t of
110-
Left errMsg -> panic $ pack errMsg
111-
Right bs -> return bs
112-
113-
setSecret bs = conf {configJwtSecret = bs}
114-
115-
-- replace: Replace every occurrence of one substring with another
116-
replaceUrlChars =
117-
replace "_" "/" . replace "-" "+" . replace "." "="
18+
conf <- loadConfig
19+
void $ serve conf

postgres-websockets.cabal

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ library
2020
, PostgresWebsockets.Broadcast
2121
, PostgresWebsockets.HasqlBroadcast
2222
, PostgresWebsockets.Claims
23+
, PostgresWebsockets.Config
24+
25+
other-modules: Paths_postgres_websockets
26+
, PostgresWebsockets.Server
27+
, PostgresWebsockets.Middleware
2328
build-depends: base >= 4.7 && < 5
2429
, hasql-pool >= 0.5 && < 0.6
2530
, text >= 1.2 && < 1.3
@@ -46,32 +51,25 @@ library
4651
, contravariant >= 1.5.2 && < 1.6
4752
, alarmclock >= 0.7.0.2 && < 0.8
4853
, async >= 2.2.0 && < 2.3
54+
, envparse >= 0.4.1
55+
, base64-bytestring >= 1.0.0.3 && < 1.1
56+
, bytestring >= 0.10
57+
, warp >= 3.2 && < 4
58+
, wai-extra >= 3.0.29 && < 3.1
59+
, wai-app-static >= 3.1.7.1 && < 3.2
60+
, auto-update >= 0.1.6 && < 0.2
61+
4962
default-language: Haskell2010
50-
default-extensions: OverloadedStrings, NoImplicitPrelude, LambdaCase
63+
default-extensions: OverloadedStrings, NoImplicitPrelude, LambdaCase, RecordWildCards
5164

5265
executable postgres-websockets
5366
hs-source-dirs: app
5467
main-is: Main.hs
55-
other-modules: Config
56-
, Paths_postgres_websockets
68+
other-modules:
5769
ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
5870
build-depends: base >= 4.7 && < 5
59-
, transformers >= 0.4 && < 0.6
60-
, hasql >= 0.19
61-
, hasql-pool >= 0.4
62-
, warp >= 3.2 && < 4
6371
, postgres-websockets
6472
, protolude >= 0.2.3
65-
, base64-bytestring >= 1.0.0.3 && < 1.1
66-
, bytestring >= 0.10
67-
, text >= 1.2 && < 1.3
68-
, time >= 1.8.0.2 && < 1.9
69-
, wai >= 3.2 && < 4
70-
, wai-extra >= 3.0.29 && < 3.1
71-
, wai-app-static >= 3.1.7.1 && < 3.2
72-
, http-types >= 0.9
73-
, envparse >= 0.4.1
74-
, auto-update >= 0.1.6 && < 0.2
7573
default-language: Haskell2010
7674
default-extensions: OverloadedStrings, NoImplicitPrelude, QuasiQuotes
7775

@@ -82,6 +80,7 @@ test-suite postgres-websockets-test
8280
other-modules: BroadcastSpec
8381
, ClaimsSpec
8482
, HasqlBroadcastSpec
83+
, ServerSpec
8584
build-depends: base
8685
, protolude >= 0.2.3
8786
, postgres-websockets
@@ -97,6 +96,10 @@ test-suite postgres-websockets-test
9796
, unordered-containers >= 0.2
9897
, wai-extra >= 3.0.29 && < 3.1
9998
, stm >= 2.5.0.0 && < 2.6
99+
, websockets >= 0.12.7.0 && < 0.13
100+
, network >= 2.8.0.1 && < 2.9
101+
, lens >= 4.17.1 && < 4.18
102+
, lens-aeson
100103
ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
101104
default-language: Haskell2010
102105
default-extensions: OverloadedStrings, NoImplicitPrelude

0 commit comments

Comments
 (0)