Skip to content

Commit c9af7e3

Browse files
dpwizepoberezkin
andauthored
smp server: graceful shutdown on SIGINT (#1360)
* smp-server: graceful shutdown on SIGINT * .501 * clean up * remove version --------- Co-authored-by: Evgeny Poberezkin <[email protected]>
1 parent 8870442 commit c9af7e3

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

apps/smp-server/web/Static.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,22 @@ serveStaticFiles EmbeddedWebParams {webStaticPath, webHttpPort, webHttpsParams}
4242
WT.runTLS (WT.tlsSettings cert key) (mkSettings port) app
4343
where
4444
app = staticFiles webStaticPath
45-
mkSettings port = W.setPort port W.defaultSettings
45+
mkSettings port = W.setPort port warpSettings
4646

4747
-- | Prepare context and prepare HTTP handler for TLS connections that already passed TLS.handshake and ALPN check.
4848
attachStaticFiles :: FilePath -> (AttachHTTP -> IO ()) -> IO ()
4949
attachStaticFiles path action =
5050
-- Initialize global internal state for http server.
51-
WI.withII settings $ \ii -> do
51+
WI.withII warpSettings $ \ii -> do
5252
action $ \socket cxt -> do
5353
-- Initialize internal per-connection resources.
5454
addr <- getPeerName socket
5555
withConnection addr cxt $ \(conn, transport) ->
5656
withTimeout ii conn $ \th ->
5757
-- Run Warp connection handler to process HTTP requests for static files.
58-
WI.serveConnection conn ii th addr transport settings app
58+
WI.serveConnection conn ii th addr transport warpSettings app
5959
where
6060
app = staticFiles path
61-
settings = W.defaultSettings
6261
-- from warp-tls
6362
withConnection socket cxt = bracket (WT.attachConn socket cxt) (terminate . fst)
6463
-- from warp
@@ -69,6 +68,9 @@ attachStaticFiles path action =
6968
-- shared clean up
7069
terminate conn = WI.connClose conn `finally` (readIORef (WI.connWriteBuffer conn) >>= WI.bufFree)
7170

71+
warpSettings :: W.Settings
72+
warpSettings = W.setGracefulShutdownTimeout (Just 1) W.defaultSettings
73+
7274
staticFiles :: FilePath -> Application
7375
staticFiles root = S.staticApp settings
7476
where

src/Simplex/Messaging/Server.hs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import qualified Data.ByteString.Builder as BLD
5353
import Data.ByteString.Char8 (ByteString)
5454
import qualified Data.ByteString.Char8 as B
5555
import qualified Data.ByteString.Lazy.Char8 as LB
56+
import Data.Dynamic (toDyn)
5657
import Data.Either (fromRight, partitionEithers)
5758
import Data.Functor (($>))
5859
import Data.IORef
@@ -71,6 +72,7 @@ import Data.Time.Clock.System (SystemTime (..), getSystemTime)
7172
import Data.Time.Format.ISO8601 (iso8601Show)
7273
import Data.Type.Equality
7374
import Data.Typeable (cast)
75+
import GHC.Conc.Signal
7476
import GHC.IORef (atomicSwapIORef)
7577
import GHC.Stats (getRTSStats)
7678
import GHC.TypeLits (KnownNat)
@@ -149,9 +151,10 @@ smpServer started cfg@ServerConfig {transports, transportConfig = tCfg} attachHT
149151
: sendPendingEvtsThread s
150152
: receiveFromProxyAgent pa
151153
: expireNtfsThread cfg
154+
: sigIntHandlerThread
152155
: map runServer transports <> expireMessagesThread_ cfg <> serverStatsThread_ cfg <> controlPortThread_ cfg
153156
)
154-
`finally` withLock' (savingLock s) "final" (saveServer False >> closeServer)
157+
`finally` stopServer s
155158
where
156159
runServer :: (ServiceName, ATransport, AddHTTP) -> M ()
157160
runServer (tcpPort, ATransport t, addHTTP) = do
@@ -175,6 +178,22 @@ smpServer started cfg@ServerConfig {transports, transportConfig = tCfg} attachHT
175178
runTransportServerState ss started tcpPort defaultSupportedParams smpCreds (Just supportedSMPHandshakes) tCfg $ \h -> runClient serverSignKey t h `runReaderT` env
176179
fromTLSCredentials (_, pk) = C.x509ToPrivate (pk, []) >>= C.privKey
177180

181+
sigIntHandlerThread :: M ()
182+
sigIntHandlerThread = do
183+
flagINT <- newEmptyTMVarIO
184+
let sigINT = 2 -- CONST_SIGINT value
185+
sigIntAction = \_ptr -> atomically $ void $ tryPutTMVar flagINT ()
186+
sigIntHandler = Just (sigIntAction, toDyn ())
187+
void $ liftIO $ setHandler sigINT sigIntHandler
188+
atomically $ readTMVar flagINT
189+
logInfo "Received SIGINT, stopping server..."
190+
191+
stopServer :: Server -> M ()
192+
stopServer s = do
193+
logInfo "Saving server state..."
194+
withLock' (savingLock s) "final" $ saveServer False >> closeServer
195+
logInfo "Server stopped"
196+
178197
saveServer :: Bool -> M ()
179198
saveServer keepMsgs = withLog closeStoreLog >> saveServerMessages keepMsgs >> saveServerNtfs >> saveServerStats
180199

src/Simplex/Messaging/Server/Main.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
module Simplex.Messaging.Server.Main where
1515

1616
import Control.Concurrent.STM
17+
import Control.Exception (finally)
1718
import Control.Logger.Simple
1819
import Control.Monad
1920
import Data.ByteString.Char8 (ByteString)
@@ -280,13 +281,16 @@ smpServerCLI_ generateSite serveStaticFiles attachStaticFiles cfgPath logPath =
280281
case webStaticPath' of
281282
Just path | sharedHTTP -> do
282283
runWebServer path Nothing ServerInformation {config, information}
283-
attachStaticFiles path $ \attachHTTP -> runSMPServer cfg $ Just attachHTTP
284+
attachStaticFiles path $ \attachHTTP -> do
285+
logDebug "Allocated web server resources"
286+
runSMPServer cfg (Just attachHTTP) `finally` logDebug "Releasing web server resources..."
284287
Just path -> do
285288
runWebServer path webHttpsParams' ServerInformation {config, information}
286289
runSMPServer cfg Nothing
287290
Nothing -> do
288291
logWarn "No server static path set"
289292
runSMPServer cfg Nothing
293+
logDebug "Bye"
290294
where
291295
enableStoreLog = settingIsOn "STORE_LOG" "enable" ini
292296
logStats = settingIsOn "STORE_LOG" "log_stats" ini

0 commit comments

Comments
 (0)