Skip to content

Commit b0f9405

Browse files
authored
Merge pull request #57 from diogob/shutdown-on-connection-failure
Shutdown server if listener connection dies
2 parents a4c0e55 + 63c7e08 commit b0f9405

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

app/Main.hs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,32 @@ main = do
5252
<> " / Connects websockets to PostgreSQL asynchronous notifications."
5353

5454
conf <- loadSecretFile =<< readOptions
55+
shutdownSignal <- newEmptyMVar
5556
let host = configHost conf
5657
port = configPort conf
5758
listenChannel = toS $ configListenChannel conf
5859
pgSettings = toS (configDatabase conf)
60+
waitForShutdown cl = void $ forkIO (takeMVar shutdownSignal >> cl >> die "Shutting server down...")
61+
5962
appSettings = setHost ((fromString . toS) host)
6063
. setPort port
6164
. setServerName (toS $ "postgres-websockets/" <> prettyVersion)
6265
. setTimeout 3600
66+
. setInstallShutdownHandler waitForShutdown
67+
. setGracefulShutdownTimeout (Just 5)
6368
$ defaultSettings
6469

6570
putStrLn $ ("Listening on port " :: Text) <> show (configPort conf)
6671

72+
let shutdown = putErrLn ("Broadcaster connection is dead" :: Text) >> putMVar shutdownSignal ()
6773
pool <- P.acquire (configPool conf, 10, pgSettings)
68-
multi <- newHasqlBroadcaster listenChannel pgSettings
74+
multi <- newHasqlBroadcaster shutdown listenChannel pgSettings
6975
getTime <- mkGetTime
7076

7177
runSettings appSettings $
7278
postgresWsMiddleware getTime listenChannel (configJwtSecret conf) pool multi $
7379
logStdout $ maybe dummyApp staticApp' (configPath conf)
80+
7481
where
7582
mkGetTime :: IO (IO UTCTime)
7683
mkGetTime = mkAutoUpdate defaultUpdateSettings {updateAction = getCurrentTime}

src/PostgresWebsockets/HasqlBroadcast.hs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@ import PostgresWebsockets.Broadcast
2626
{- | Returns a multiplexer from a connection URI, keeps trying to connect in case there is any error.
2727
This function also spawns a thread that keeps relaying the messages from the database to the multiplexer's listeners
2828
-}
29-
newHasqlBroadcaster :: Text -> ByteString -> IO Multiplexer
30-
newHasqlBroadcaster ch = newHasqlBroadcasterForConnection . tryUntilConnected
29+
newHasqlBroadcaster :: IO () -> Text -> ByteString -> IO Multiplexer
30+
newHasqlBroadcaster onConnectionFailure ch = newHasqlBroadcasterForConnection . tryUntilConnected
3131
where
32-
newHasqlBroadcasterForConnection = newHasqlBroadcasterForChannel ch
32+
newHasqlBroadcasterForConnection = newHasqlBroadcasterForChannel onConnectionFailure ch
3333

3434
{- | Returns a multiplexer from a connection URI or an error message on the left case
3535
This function also spawns a thread that keeps relaying the messages from the database to the multiplexer's listeners
3636
-}
37-
newHasqlBroadcasterOrError :: Text -> ByteString -> IO (Either ByteString Multiplexer)
38-
newHasqlBroadcasterOrError ch =
37+
newHasqlBroadcasterOrError :: IO () -> Text -> ByteString -> IO (Either ByteString Multiplexer)
38+
newHasqlBroadcasterOrError onConnectionFailure ch =
3939
acquire >=> (sequence . mapBoth show (newHasqlBroadcasterForConnection . return))
4040
where
41-
newHasqlBroadcasterForConnection = newHasqlBroadcasterForChannel ch
41+
newHasqlBroadcasterForConnection = newHasqlBroadcasterForChannel onConnectionFailure ch
4242

4343
tryUntilConnected :: ByteString -> IO Connection
4444
tryUntilConnected =
@@ -78,13 +78,12 @@ tryUntilConnected =
7878
@
7979
8080
-}
81-
newHasqlBroadcasterForChannel :: Text -> IO Connection -> IO Multiplexer
82-
newHasqlBroadcasterForChannel ch getCon = do
83-
multi <- newMultiplexer openProducer closeProducer
81+
newHasqlBroadcasterForChannel :: IO () -> Text -> IO Connection -> IO Multiplexer
82+
newHasqlBroadcasterForChannel onConnectionFailure ch getCon = do
83+
multi <- newMultiplexer openProducer $ const onConnectionFailure
8484
void $ relayMessagesForever multi
8585
return multi
8686
where
87-
closeProducer _ = putErrLn "Broadcaster is dead"
8887
toMsg :: ByteString -> ByteString -> Message
8988
toMsg c m = case decode (toS m) of
9089
Just v -> Message (channelDef c v) m

test/HasqlBroadcastSpec.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ spec = describe "newHasqlBroadcaster" $ do
1515
<$> acquire connStr
1616

1717
it "relay messages sent to the appropriate database channel" $ do
18-
multi <- either (panic .show) id <$> newHasqlBroadcasterOrError "postgres-websockets" "postgres://localhost/postgres_ws_test"
18+
multi <- either (panic .show) id <$> newHasqlBroadcasterOrError (pure ()) "postgres-websockets" "postgres://localhost/postgres_ws_test"
1919
msg <- liftIO newEmptyMVar
2020
onMessage multi "test" $ putMVar msg
2121

0 commit comments

Comments
 (0)