Skip to content

Commit 83140cf

Browse files
committed
restart only on cache changed
1 parent 0a4f695 commit 83140cf

File tree

2 files changed

+40
-32
lines changed
  • ghcide/session-loader/Development/IDE
  • hls-graph/src/Development/IDE/Graph/Internal

2 files changed

+40
-32
lines changed

ghcide/session-loader/Development/IDE/Session.hs

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import Control.Monad
2828
import Control.Monad.Extra as Extra
2929
import Control.Monad.IO.Class
3030
import qualified Crypto.Hash.SHA1 as H
31-
import Data.Aeson hiding (Error)
31+
-- import Data.Aeson hiding (Error)
3232
import Data.Bifunctor
3333
import qualified Data.ByteString.Base16 as B16
3434
import qualified Data.ByteString.Char8 as B
@@ -108,7 +108,8 @@ import qualified Data.HashSet as Set
108108
import Database.SQLite.Simple
109109
import Development.IDE.Core.Tracing (withTrace)
110110
import Development.IDE.Session.Diagnostics (renderCradleError)
111-
import Development.IDE.Types.Shake (WithHieDb, toNoFileKey)
111+
import Development.IDE.Types.Shake (Key, WithHieDb,
112+
toNoFileKey)
112113
import HieDb.Create
113114
import HieDb.Types
114115
import HieDb.Utils
@@ -134,6 +135,7 @@ import GHC.Unit.State
134135
import Language.LSP.Protocol.Types (NormalizedUri (NormalizedUri),
135136
toNormalizedFilePath)
136137
#endif
138+
import Data.Aeson (ToJSON (toJSON))
137139
import Development.IDE (RuleResult)
138140
import qualified Development.IDE.Core.Shake as SHake
139141

@@ -449,7 +451,7 @@ getHieDbLoc dir = do
449451
loadSession :: Recorder (WithPriority Log) -> FilePath -> IO (Rules (), Action IdeGhcSession)
450452
loadSession recorder = loadSessionWithOptions recorder def
451453

452-
type instance RuleResult HieYaml = (IdeResult HscEnvEq, [FilePath])
454+
type instance RuleResult HieYaml = (IdeResult HscEnvEq, [FilePath], [NormalizedFilePath], [Key])
453455

454456
loadSessionWithOptions :: Recorder (WithPriority Log) -> SessionLoadingOptions -> FilePath -> IO (Rules (), Action IdeGhcSession)
455457
loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
@@ -470,6 +472,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
470472

471473
-- version of the whole rebuild
472474
cacheVersion <- newVar 0
475+
lastRestartVersion <- newVar 0
473476
cradleLock <- newMVar ()
474477
-- putMVar cradleLock ()
475478
biosSessionLoadingVar <- newVar Nothing :: IO (Var (Maybe SessionLoadingPreferenceConfig))
@@ -502,11 +505,20 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
502505
liftIO $ writeVar biosSessionLoadingVar (Just (sessionLoading clientConfig))
503506
pure (loadingConfig /= sessionLoading clientConfig)
504507

508+
let typecheckAll cfps' =
509+
mkDelayedAction "InitialLoad" Debug $ void $ do
510+
mmt <- uses GetModificationTime cfps'
511+
let cs_exist = catMaybes (zipWith (<$) cfps' mmt)
512+
modIfaces <- uses GetModIface cs_exist
513+
-- update exports map
514+
shakeExtras <- getShakeExtras
515+
let !exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
516+
liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <>)
505517

506-
let session :: (Maybe FilePath, NormalizedFilePath, ComponentOptions, FilePath)
507-
-> Action (IdeResult HscEnvEq,[FilePath])
508-
session args@(hieYaml, _cfp, _opts, _libDir) = do
509-
ShakeExtras{restartShakeSession, ideNc} <- getShakeExtras
518+
-- let session :: (Maybe FilePath, NormalizedFilePath, ComponentOptions, FilePath)
519+
-- -> Action (IdeResult HscEnvEq,[FilePath])
520+
let session args@(hieYaml, _cfp, _opts, _libDir) = do
521+
ShakeExtras{ideNc} <- getShakeExtras
510522
IdeOptions{ optCheckProject = getCheckProject , optExtensions } <- getIdeOptions
511523
(new_deps, old_deps) <- packageSetup args
512524

@@ -542,24 +554,9 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
542554
keys1 <- extendKnownTargets all_targets
543555

544556
-- Typecheck all files in the project on startup
545-
checkProject <- liftIO getCheckProject
546557
cfps' <- liftIO $ filterM (IO.doesFileExist . fromNormalizedFilePath) (concatMap targetLocations all_targets)
547-
let typeCheckAll = if null new_deps || not checkProject
548-
then []
549-
else return $
550-
mkDelayedAction "InitialLoad" Debug $ void $ do
551-
mmt <- uses GetModificationTime cfps'
552-
let cs_exist = catMaybes (zipWith (<$) cfps' mmt)
553-
modIfaces <- uses GetModIface cs_exist
554-
-- update exports map
555-
shakeExtras <- getShakeExtras
556-
let !exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
557-
liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <>)
558-
-- todo this should be moving out of the session function
559-
restart <- liftIO $ async $ do
560-
restartShakeSession VFSUnmodified "new component" typeCheckAll $ pure [keys1, keys2]
561-
UnliftIO.wait restart
562-
return $ second Map.keys this_options
558+
let (x, y) = this_options
559+
return $ (x, Map.keys y, cfps', [keys1, keys2])
563560

564561
-- Create a new HscEnv from a hieYaml root and a set of options
565562
packageSetup :: (Maybe FilePath, NormalizedFilePath, ComponentOptions, FilePath)
@@ -664,7 +661,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
664661

665662
-- -- This caches the mapping from hie.yaml + Mod.hs -> [String]
666663
-- -- Returns the Ghc session and the cradle dependencies
667-
consultCradle :: NormalizedFilePath -> Action (IdeResult HscEnvEq, [FilePath])
664+
-- consultCradle :: NormalizedFilePath -> Action (IdeResult HscEnvEq, [FilePath])
668665
consultCradle cfp = do
669666
clientConfig <- getClientConfigAction
670667
ShakeExtras{lspEnv } <- getShakeExtras
@@ -701,7 +698,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
701698
InstallationNotFound{..} ->
702699
error $ "GHC installation not found in libdir: " <> libdir
703700
InstallationMismatch{..} ->
704-
return (([renderPackageSetupException cfp GhcVersionMismatch{..}], Nothing),[])
701+
return (([renderPackageSetupException cfp GhcVersionMismatch{..}], Nothing),[], [], [])
705702
InstallationChecked _compileTime _ghcLibCheck -> do
706703
liftIO $ atomicModifyIORef' cradle_files (\xs -> (fromNormalizedFilePath cfp:xs,()))
707704
session (hieYaml, cfp, opts, libDir)
@@ -712,7 +709,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
712709
liftIO $ void $ modifyVar' fileToFlags $
713710
Map.insertWith HM.union hieYaml (HM.singleton cfp (res, dep_info))
714711
liftIO $ void $ modifyVar' filesMap $ HM.insert cfp hieYaml
715-
return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
712+
return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err,[],[])
716713

717714
sessionCacheVersionRule :: Rules ()
718715
sessionCacheVersionRule = defineNoFile (cmapWithPrio LogShake recorder) $ \SessionCacheVersion -> do
@@ -737,7 +734,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
737734
-- install cache version check to avoid recompilation
738735
_ <- useNoFile_ SessionCacheVersion
739736
catchError file hieYaml $ do
740-
result@(_, deps) <- consultCradle file
737+
result@(_, deps, _, _) <- consultCradle file
741738
-- add the deps to the Shake graph
742739
mapM_ addDependency deps
743740
return $ Just result
@@ -746,7 +743,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
746743
f `Safe.catch` \e -> do
747744
-- install dep so it can be recorvered
748745
mapM_ addDependency hieYaml
749-
return $ Just (([renderPackageSetupException file e], Nothing), maybe [] pure hieYaml)
746+
return $ Just (([renderPackageSetupException file e], Nothing), maybe [] pure hieYaml, [], [])
750747
addDependency fp = do
751748
-- VSCode uses absolute paths in its filewatch notifications
752749
let nfp = toNormalizedFilePath' fp
@@ -770,9 +767,20 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
770767
-- at a time. Therefore the IORef contains the currently running cradle, if we try
771768
-- to get some more options then we wait for the currently running action to finish
772769
-- before attempting to do so.
770+
ShakeExtras{restartShakeSession } <- getShakeExtras
771+
IdeOptions{ optCheckProject = getCheckProject} <- getIdeOptions
773772
returnWithVersion $ \file -> do
774-
opts <- use_ HieYaml file
775-
pure $ (fmap . fmap) toAbsolutePath opts)
773+
_opts@(a, b, files, keys) <- use_ HieYaml file
774+
-- wait for the restart
775+
lastRestartVersion' <- liftIO $ readVar lastRestartVersion
776+
cacheVersion' <- liftIO $ readVar cacheVersion
777+
liftIO $ when ((notNull files || notNull keys) && lastRestartVersion' /= cacheVersion') $ do
778+
liftIO $ writeVar lastRestartVersion cacheVersion'
779+
checkProject <- getCheckProject
780+
-- think of not to restart a second time
781+
async <- UnliftIO.async $ restartShakeSession VFSUnmodified "new component" (if checkProject then return (typecheckAll files) else mempty) $ pure keys
782+
UnliftIO.wait async
783+
pure $ (fmap . fmap) toAbsolutePath (a, b))
776784

777785

778786
-- | Run the specific cradle on a specific FilePath via hie-bios.

hls-graph/src/Development/IDE/Graph/Internal/Key.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import Development.IDE.Graph.Classes
4949
import System.IO.Unsafe
5050

5151

52-
newtype Key = UnsafeMkKey Int
52+
newtype Key = UnsafeMkKey Int deriving (NFData)
5353

5454
pattern Key :: () => (Typeable a, Hashable a, Show a) => a -> Key
5555
pattern Key a <- (lookupKeyValue -> KeyValue a _)

0 commit comments

Comments
 (0)