Skip to content

Commit 099e17f

Browse files
committed
push the update of config to reactor thread
1 parent e96a53e commit 099e17f

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed

ghcide/src/Development/IDE/LSP/LanguageServer.hs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -128,25 +128,18 @@ setupLSP ::
128128
-> (FilePath -> IO FilePath) -- ^ Map root paths to the location of the hiedb for the project
129129
-> LSP.Handlers (ServerM config)
130130
-> (LSP.LanguageContextEnv config -> Maybe FilePath -> WithHieDb -> IndexQueue -> IO IdeState)
131+
-> Chan ReactorMessage
131132
-> MVar ()
132133
-> IO (LSP.LanguageContextEnv config -> TRequestMessage Method_Initialize -> IO (Either err (LSP.LanguageContextEnv config, IdeState)),
133134
LSP.Handlers (ServerM config),
134135
(LanguageContextEnv config, IdeState) -> ServerM config <~> IO)
135-
setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgVar = do
136-
-- Send everything over a channel, since you need to wait until after initialise before
137-
-- LspFuncs is available
138-
clientMsgChan :: Chan ReactorMessage <- newChan
136+
setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgChan clientMsgVar = do
139137

140138
-- An MVar to control the lifetime of the reactor loop.
141139
-- The loop will be stopped and resources freed when it's full
142140
reactorLifetime <- newEmptyMVar
143141
let stopReactorLoop = void $ tryPutMVar reactorLifetime ()
144142

145-
-- An MVar to control the lifetime of the reactor loop.
146-
-- The loop will be stopped and resources freed when it's full
147-
waitForReactor <- newEmptyMVar
148-
let finishEndReactor = void $ tryPutMVar waitForReactor ()
149-
150143
-- Forcefully exit
151144
let exit = void $ tryPutMVar clientMsgVar ()
152145

@@ -171,18 +164,17 @@ setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgVar = do
171164
cancelled <- readTVar cancelledRequests
172165
unless (reqId `Set.member` cancelled) retry
173166

174-
175-
let doInitialize = handleInit recorder getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan finishEndReactor
176-
177167
let asyncHandlers = mconcat
178168
[ userHandlers
179169
, cancelHandler cancelRequest
180-
, exitHandler $ stopReactorLoop >> takeMVar waitForReactor >> exit
170+
, exitHandler exit
181171
, shutdownHandler stopReactorLoop
182172
]
183173
-- Cancel requests are special since they need to be handled
184174
-- out of order to be useful. Existing handlers are run afterwards.
185175

176+
let doInitialize = handleInit recorder getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan
177+
186178
let interpretHandler (env, st) = LSP.Iso (LSP.runLspT env . flip (runReaderT . unServerM) (clientMsgChan,st)) liftIO
187179

188180
pure (doInitialize, asyncHandlers, interpretHandler)
@@ -197,10 +189,8 @@ handleInit
197189
-> (SomeLspId -> IO ())
198190
-> (SomeLspId -> IO ())
199191
-> Chan ReactorMessage
200-
-> IO ()
201-
-> LSP.LanguageContextEnv config -> TRequestMessage Method_Initialize
202-
-> IO (Either err (LSP.LanguageContextEnv config, IdeState))
203-
handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId waitForCancel clientMsgChan finishEndReactor env (TRequestMessage _ _ m params) = otTracedHandler "Initialize" (show m) $ \sp -> do
192+
-> LSP.LanguageContextEnv config -> TRequestMessage Method_Initialize -> IO (Either err (LSP.LanguageContextEnv config, IdeState))
193+
handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId waitForCancel clientMsgChan env (TRequestMessage _ _ m params) = otTracedHandler "Initialize" (show m) $ \sp -> do
204194
traceWithSpan sp params
205195
let root = LSP.resRootPath env
206196
dir <- maybe getCurrentDirectory return root
@@ -253,7 +243,6 @@ handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId wa
253243
ReactorNotification act -> handle exceptionInHandler act
254244
ReactorRequest _id act k -> void $ async $ checkCancelled _id act k
255245
logWith recorder Info LogReactorThreadStopped
256-
finishEndReactor
257246
pure $ Right (env,ide)
258247

259248

@@ -275,7 +264,7 @@ shutdownHandler stopReactor = LSP.requestHandler SMethod_Shutdown $ \_ resp -> d
275264
(_, ide) <- ask
276265
liftIO $ logDebug (ideLogger ide) "Received shutdown message"
277266
-- stop the reactor to free up the hiedb connection
278-
-- liftIO stopReactor
267+
liftIO stopReactor
279268
-- flush out the Shake session to record a Shake profile if applicable
280269
liftIO $ shakeShut ide
281270
resp $ Right Null

ghcide/src/Development/IDE/Main.hs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ module Development.IDE.Main
1111
,Log(..)
1212
) where
1313

14-
import Control.Concurrent.Extra (withNumCapabilities)
14+
import Control.Concurrent.Extra (Chan, newChan,
15+
withNumCapabilities,
16+
writeChan)
1517
import Control.Concurrent.MVar (newEmptyMVar,
1618
putMVar, tryReadMVar)
1719
import Control.Concurrent.STM.Stats (dumpSTMStats)
@@ -63,6 +65,7 @@ import Development.IDE.Graph (action)
6365
import Development.IDE.LSP.LanguageServer (runLanguageServer,
6466
setupLSP)
6567
import qualified Development.IDE.LSP.LanguageServer as LanguageServer
68+
import Development.IDE.LSP.Server
6669
import Development.IDE.Main.HeapStats (withHeapStats)
6770
import qualified Development.IDE.Main.HeapStats as HeapStats
6871
import qualified Development.IDE.Monitoring.EKG as EKG
@@ -356,19 +359,26 @@ defaultMain recorder Arguments{..} = withHeapStats (cmapWithPrio LogHeapStats re
356359
putMVar ideStateVar ide
357360
pure ide
358361

359-
let setup = setupLSP (cmapWithPrio LogLanguageServer recorder) argsGetHieDbLoc (pluginHandlers plugins) getIdeState
362+
-- Send everything over a channel, since you need to wait until after initialise before
363+
-- LspFuncs is available
364+
clientMsgChan :: Chan ReactorMessage <- newChan
365+
366+
let setup = setupLSP (cmapWithPrio LogLanguageServer recorder) argsGetHieDbLoc (pluginHandlers plugins) getIdeState clientMsgChan
360367
-- See Note [Client configuration in Rules]
361368
onConfigChange cfg = do
362369
-- TODO: this is nuts, we're converting back to JSON just to get a fingerprint
363370
let cfgObj = J.toJSON cfg
364-
mide <- liftIO $ tryReadMVar ideStateVar
365-
case mide of
366-
Nothing -> pure ()
367-
Just ide -> liftIO $ do
368-
let msg = T.pack $ show cfg
369-
logDebug (Shake.ideLogger ide) $ "Configuration changed: " <> msg
370-
modifyClientSettings ide (const $ Just cfgObj)
371-
setSomethingModified Shake.VFSUnmodified ide [toKey Rules.GetClientSettings emptyFilePath] "config change"
371+
let configChangeIO = do
372+
mide <- liftIO $ tryReadMVar ideStateVar
373+
case mide of
374+
Nothing -> pure ()
375+
Just ide -> liftIO $ do
376+
let msg = T.pack $ show cfg
377+
logDebug (Shake.ideLogger ide) $ "Configuration changed: " <> msg
378+
modifyClientSettings ide (const $ Just cfgObj)
379+
setSomethingModified Shake.VFSUnmodified ide [toKey Rules.GetClientSettings emptyFilePath] "config change"
380+
liftIO $ writeChan clientMsgChan $ ReactorNotification configChangeIO
381+
372382

373383
runLanguageServer (cmapWithPrio LogLanguageServer recorder) options inH outH argsDefaultHlsConfig argsParseConfig onConfigChange setup
374384
dumpSTMStats

0 commit comments

Comments
 (0)