@@ -92,6 +92,7 @@ instance Pretty LspProcessingLog where
92
92
processMessage :: (m ~ LspM config ) => LogAction m (WithSeverity LspProcessingLog ) -> BSL. ByteString -> m ()
93
93
processMessage logger jsonStr = do
94
94
pendingResponsesVar <- LspT $ asks $ resPendingResponses . resState
95
+ shutdown <- isShuttingDown
95
96
join $ liftIO $ atomically $ fmap handleErrors $ runExceptT $ do
96
97
val <- except $ eitherDecode jsonStr
97
98
pending <- lift $ readTVar pendingResponsesVar
@@ -100,8 +101,10 @@ processMessage logger jsonStr = do
100
101
FromClientMess m mess ->
101
102
pure $ handle logger m mess
102
103
FromClientRsp (P. Pair (ServerResponseCallback f) (Const ! newMap)) res -> do
104
+ -- see Note [Shutdown]
103
105
writeTVar pendingResponsesVar newMap
104
- pure $ liftIO $ f (res ^. L. result)
106
+ unless shutdown <$> do
107
+ pure $ liftIO $ f (res ^. L. result)
105
108
where
106
109
parser :: ResponseMap -> Value -> Parser (FromClientMessage' (P. Product ServerResponseCallback (Const ResponseMap )))
107
110
parser rm = parseClientMessage $ \ i ->
@@ -449,31 +452,37 @@ handle' ::
449
452
TClientMessage meth ->
450
453
m ()
451
454
handle' logger mAction m msg = do
452
- maybe (return () ) (\ f -> f msg) mAction
455
+ shutdown <- isShuttingDown
456
+ -- These are the methods that we are allowed to process during shutdown.
457
+ -- The reason that we do not include 'shutdown' itself here is because
458
+ -- by the time we get the first 'shutdown' message, isShuttingDown will
459
+ -- still be false, so we would still be able to process it.
460
+ -- This ensures we won't process the second 'shutdown' message and only
461
+ -- process 'exit' during shutdown.
462
+ let allowedMethod m = case (splitClientMethod m, m) of
463
+ (IsClientNot , SMethod_Exit ) -> True
464
+ _ -> False
465
+
466
+ case mAction of
467
+ Just f | not shutdown || allowedMethod m -> f msg
468
+ _ -> pure ()
453
469
454
470
dynReqHandlers <- getsState resRegistrationsReq
455
471
dynNotHandlers <- getsState resRegistrationsNot
456
472
457
473
env <- getLspEnv
458
474
let Handlers {reqHandlers, notHandlers} = resHandlers env
459
- shutdown <- isShuttingDown
460
475
461
476
case splitClientMethod m of
462
477
-- See Note [Shutdown]
463
478
IsClientNot | shutdown, not (allowedMethod m) -> notificationDuringShutdown
464
- where
465
- allowedMethod SMethod_Exit = True
466
- allowedMethod _ = False
467
479
IsClientNot -> case pickHandler dynNotHandlers notHandlers of
468
480
Just h -> liftIO $ h msg
469
481
Nothing
470
482
| SMethod_Exit <- m -> exitNotificationHandler logger msg
471
483
| otherwise -> missingNotificationHandler
472
484
-- See Note [Shutdown]
473
485
IsClientReq | shutdown, not (allowedMethod m) -> requestDuringShutdown msg
474
- where
475
- allowedMethod SMethod_Shutdown = True
476
- allowedMethod _ = False
477
486
IsClientReq -> case pickHandler dynReqHandlers reqHandlers of
478
487
Just h -> liftIO $ h msg (runLspT env . sendResponse msg)
479
488
Nothing
0 commit comments