Skip to content

Commit 067cc17

Browse files
committed
feat(server): add sender shutdown timeout logging and handling
1 parent f015902 commit 067cc17

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

lsp/src/Language/LSP/Server/Control.hs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ module Language.LSP.Server.Control (
1212
import Colog.Core (LogAction (..), Severity (..), WithSeverity (..), (<&))
1313
import Colog.Core qualified as L
1414
import Control.Applicative ((<|>))
15-
import Control.Concurrent.Async (withAsync)
15+
import Control.Concurrent.Async (withAsync, wait, cancel, race)
16+
import Control.Concurrent (threadDelay)
1617
import Control.Concurrent.STM.TChan
1718
import Control.Exception (catchJust, throwIO)
1819
import Control.Monad.IO.Class
@@ -44,6 +45,7 @@ data LspServerLog
4445
| BrokenPipeWhileSending TL.Text -- truncated outgoing message (including header)
4546
| Starting
4647
| ServerStopped
48+
| SenderShutdownTimeout -- client sender did not stop in time
4749
| ParsedMsg T.Text
4850
| SendMsg TL.Text
4951
deriving (Show)
@@ -70,6 +72,7 @@ instance Pretty LspServerLog where
7072
pretty Starting = "Server starting"
7173
pretty (ParsedMsg msg) = "---> " <> pretty msg
7274
pretty (SendMsg msg) = "<--2-- " <> pretty msg
75+
pretty SenderShutdownTimeout = "Sender did not stop within 3s; cancelling"
7376

7477
-- ---------------------------------------------------------------------
7578

@@ -150,6 +153,14 @@ runServerWith ioLogger logger clientIn clientOut serverDefinition = do
150153
withAsync (sendServer ioLogger cout clientOut) $ \_sendAsync -> do
151154
let sendMsg = atomically . writeTChan cout
152155
res <- ioLoop ioLogger logger clientIn serverDefinition emptyVFS sendMsg
156+
-- The sender should stop after we send the shutdown response.
157+
-- Wait up to 3 seconds for the sender to finish; cancel if it doesn't.
158+
r <- race (wait _sendAsync) (threadDelay 3_000_000)
159+
case r of
160+
Left _ -> pure ()
161+
Right _ -> do
162+
ioLogger <& SenderShutdownTimeout `WithSeverity` Warning
163+
cancel _sendAsync
153164
ioLogger <& ServerStopped `WithSeverity` Info
154165
return res
155166

0 commit comments

Comments
 (0)