Skip to content

Commit

Permalink
Merge branch 'fix-stuck-at-exit' into soulomoon/mark-dirty-keys-sync-…
Browse files Browse the repository at this point in the history
…to-hls-graph1
  • Loading branch information
soulomoon committed May 5, 2024
2 parents 53e601e + a3c86b0 commit a9aeef6
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ jobs:
needs:
- pre_job
runs-on: ${{ matrix.os }}
env:
LSP_TEST_LOG_STDERR: 1
strategy:
# We don't want to fail fast.
# We used to fail fast, to avoid caches of failing PRs to overpopulate the CI
Expand Down
4 changes: 2 additions & 2 deletions ghcide/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import qualified Development.IDE.Main as IDEMain
import qualified Development.IDE.Monitoring.OpenTelemetry as OpenTelemetry
import qualified Development.IDE.Plugin.HLS.GhcIde as GhcIde
import Development.IDE.Types.Options
import Ide.Logger (LoggingColumn (DataColumn, PriorityColumn),
import Ide.Logger (LoggingColumn (..),
Pretty (pretty),
Priority (Debug, Error, Info),
WithPriority (WithPriority, priority),
Expand Down Expand Up @@ -73,7 +73,7 @@ main = withTelemetryRecorder $ \telemetryRecorder -> do
-- stderr recorder just for plugin cli commands
pluginCliRecorder <-
cmapWithPrio pretty
<$> makeDefaultStderrRecorder (Just [PriorityColumn, DataColumn])
<$> makeDefaultStderrRecorder (Just [ThreadIdColumn, PriorityColumn, DataColumn])

let hlsPlugins = pluginDescToIdePlugins (GhcIde.descriptors (cmapWithPrio LogGhcIde pluginCliRecorder))
-- WARNING: If you write to stdout before runLanguageServer
Expand Down
3 changes: 2 additions & 1 deletion ghcide/src/Development/IDE/Core/Service.hs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ initialise recorder defaultConfig plugins mainRule lspEnv debouncer options with
mainRule

-- | Shutdown the Compiler Service.
shutdown :: IdeState -> IO ()
-- shutdown :: Recorder (WithPriority Log) -> IdeState -> IO ()
shutdown :: Recorder (WithPriority Shake.Log) -> IdeState -> IO ()
shutdown = shakeShut

-- This will return as soon as the result of the action is
Expand Down
29 changes: 19 additions & 10 deletions ghcide/src/Development/IDE/Core/Shake.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ module Development.IDE.Core.Shake(
VFSModified(..), getClientConfigAction,
) where

import Control.Concurrent (tryReadMVar, withMVar)
import Control.Concurrent.Async
import Control.Concurrent.STM
import Control.Concurrent.STM.Stats (atomicallyNamed)
Expand Down Expand Up @@ -196,6 +197,7 @@ data Log
| LogShakeGarbageCollection !T.Text !Int !Seconds
-- * OfInterest Log messages
| LogSetFilesOfInterest ![(NormalizedFilePath, FileOfInterestStatus)]
| LogTimeOutShuttingDownWaitForSessionVar !Seconds
deriving Show

instance Pretty Log where
Expand Down Expand Up @@ -239,6 +241,8 @@ instance Pretty Log where
LogSetFilesOfInterest ofInterest ->
"Set files of interst to" <> Pretty.line
<> indent 4 (pretty $ fmap (first fromNormalizedFilePath) ofInterest)
LogTimeOutShuttingDownWaitForSessionVar seconds ->
"Timed out waiting for session var after" <+> pretty seconds <+> "seconds"

-- | We need to serialize writes to the database, so we send any function that
-- needs to write to the database over the channel, where it will be picked up by
Expand Down Expand Up @@ -714,16 +718,21 @@ shakeSessionInit recorder ide@IdeState{..} = do
putMVar shakeSession initSession
logWith recorder Debug LogSessionInitialised

shakeShut :: IdeState -> IO ()
shakeShut IdeState{..} = do
runner <- tryReadMVar shakeSession
-- Shake gets unhappy if you try to close when there is a running
-- request so we first abort that.
for_ runner cancelShakeSession
void $ shakeDatabaseProfile shakeDb
progressStop $ progress shakeExtras
stopMonitoring

shakeShut :: Recorder (WithPriority Log) -> IdeState -> IO ()
shakeShut recorder IdeState{..} = do
res <- timeout 1 $ withMVar shakeSession $ \runner -> do
-- Shake gets unhappy if you try to close when there is a running
-- request so we first abort that.
cancelShakeSession runner
void $ shakeDatabaseProfile shakeDb
-- might hang if there are still running
progressStop $ progress shakeExtras
stopMonitoring
case res of
Nothing -> do
logWith recorder Error $ LogTimeOutShuttingDownWaitForSessionVar 1
stopMonitoring
Just _ -> pure ()

-- | This is a variant of withMVar where the first argument is run unmasked and if it throws
-- an exception, the previous value is restored while the second argument is executed masked.
Expand Down
4 changes: 3 additions & 1 deletion ghcide/src/Development/IDE/LSP/LanguageServer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import qualified Colog.Core as Colog
import Control.Monad.IO.Unlift (MonadUnliftIO)
import Development.IDE.Core.IdeConfiguration
import Development.IDE.Core.Shake hiding (Log, Priority)
import qualified Development.IDE.Core.Shake as Shake
import Development.IDE.Core.Tracing
import qualified Development.IDE.Session as Session
import Development.IDE.Types.Shake (WithHieDb)
Expand All @@ -49,6 +50,7 @@ data Log
| LogReactorThreadStopped
| LogCancelledRequest !SomeLspId
| LogSession Session.Log
| LogShake Shake.Log
| LogLspServer LspServerLog
| LogServerShutdownMessage
deriving Show
Expand Down Expand Up @@ -265,7 +267,7 @@ shutdownHandler recorder stopReactor = LSP.requestHandler SMethod_Shutdown $ \_
-- stop the reactor to free up the hiedb connection
liftIO stopReactor
-- flush out the Shake session to record a Shake profile if applicable
liftIO $ shakeShut ide
liftIO $ shakeShut (cmapWithPrio LogShake recorder) ide
resp $ Right Null

exitHandler :: IO () -> LSP.Handlers (ServerM c)
Expand Down
3 changes: 2 additions & 1 deletion ghcide/test/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import CompletionTests
import CPPTests
import CradleTests
import DependentFileTest
import Development.IDE (LoggingColumn (..))
import DiagnosticTests
import ExceptionTests
import FindDefinitionAndHoverTests
Expand All @@ -74,7 +75,7 @@ import WatchedFileTests

main :: IO ()
main = do
docWithPriorityRecorder <- makeDefaultStderrRecorder (Just [PriorityColumn, DataColumn])
docWithPriorityRecorder <- makeDefaultStderrRecorder (Just [ThreadIdColumn, PriorityColumn, DataColumn])

let docWithFilteredPriorityRecorder =
docWithPriorityRecorder
Expand Down
1 change: 0 additions & 1 deletion hls-test-utils/src/Test/Hls/FileSystem.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ materialise rootDir' fileTree testDataDir' = do
copyDir' root dir = do
files <- fmap FP.normalise . lines <$> withCurrentDirectory (testDataDir </> dir) (readProcess "git" ["ls-files", "--cached", "--modified", "--others"] "")
mapM_ (createDirectoryIfMissing True . ((root </>) . takeDirectory)) files
mapM_ (\f -> putStrLn $ (testDataDir </> dir </> f) <> ":" <> (root </> f) ) files
mapM_ (\f -> copyFile (testDataDir </> dir </> f) (root </> f)) files
return ()

Expand Down

0 comments on commit a9aeef6

Please sign in to comment.