Skip to content

Commit 1ebd374

Browse files
fendorpepeiborramergify[bot]
authored
Add custom cache layer for session loading (#1197)
* Add custom cache layer for session loading Achieves this by adding a HashMap from NormalizedFilePath to its respective hie.yaml location. This works nicely with the existing implementation, but increases the memory usage by an considerable amount. This change is motivated by haskell/hie-bios#264 where we set the build-dir for cabal based projects to some config directory in order to avoid recompilation issues whenever users invoked `cabal build`. However, this uncovered an issue in the existing code-base, as HLS will ask for the compilation options for generated modules, such as `Paths_*`, by looking for the responsible `hie.yaml` file and using an internal cache for the options. This used to be fine, until the aforementioned hie-bios change, since now `Paths_*` module will be in some `~/.cache/hie-bios/...` directory, which has no responsible `hie.yaml` which is why we see error messages such: `No hie.yaml found, use implicit hie-bios`. * Apply suggestions from code review modifyVar with evaluate Co-authored-by: Pepe Iborra <[email protected]> Co-authored-by: Pepe Iborra <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 6559416 commit 1ebd374

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import NameCache
7070
import Packages
7171
import Control.Exception (evaluate)
7272
import Data.Void
73+
import Control.Applicative (Alternative((<|>)))
7374

7475

7576
data CacheDirs = CacheDirs
@@ -113,6 +114,11 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
113114
hscEnvs <- newVar Map.empty :: IO (Var HieMap)
114115
-- Mapping from a Filepath to HscEnv
115116
fileToFlags <- newVar Map.empty :: IO (Var FlagsMap)
117+
-- Mapping from a Filepath to its 'hie.yaml' location.
118+
-- Should hold the same Filepaths as 'fileToFlags', otherwise
119+
-- they are inconsistent. So, everywhere you modify 'fileToFlags',
120+
-- you have to modify 'filesMap' as well.
121+
filesMap <- newVar HM.empty :: IO (Var FilesMap)
116122
-- Version of the mappings above
117123
version <- newVar 0
118124
let returnWithVersion fun = IdeGhcSession fun <$> liftIO (readVar version)
@@ -271,6 +277,8 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
271277

272278
modifyVar_ fileToFlags $ \var -> do
273279
pure $ Map.insert hieYaml (HM.fromList (concatMap toFlagsMap all_targets)) var
280+
modifyVar_ filesMap $ \var -> do
281+
evaluate $ HM.union var (HM.fromList (zip (map fst $ concatMap toFlagsMap all_targets) (repeat hieYaml)))
274282

275283
extendKnownTargets all_targets
276284

@@ -329,6 +337,8 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
329337
let res = (map (renderCradleError ncfp) err, Nothing)
330338
modifyVar_ fileToFlags $ \var -> do
331339
pure $ Map.insertWith HM.union hieYaml (HM.singleton ncfp (res, dep_info)) var
340+
modifyVar_ filesMap $ \var -> do
341+
evaluate $ HM.insert ncfp hieYaml var
332342
return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
333343

334344
-- This caches the mapping from hie.yaml + Mod.hs -> [String]
@@ -358,8 +368,10 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
358368
-- before attempting to do so.
359369
let getOptions :: FilePath -> IO (IdeResult HscEnvEq, [FilePath])
360370
getOptions file = do
371+
ncfp <- toNormalizedFilePath' <$> canonicalizePath file
372+
cachedHieYamlLocation <- HM.lookup ncfp <$> readVar filesMap
361373
hieYaml <- cradleLoc file
362-
sessionOpts (hieYaml, file) `catch` \e ->
374+
sessionOpts (join cachedHieYamlLocation <|> hieYaml, file) `catch` \e ->
363375
return (([renderPackageSetupException file e], Nothing), maybe [] pure hieYaml)
364376

365377
returnWithVersion $ \file -> do
@@ -543,7 +555,11 @@ renderCradleError nfp (CradleError _ _ec t) =
543555
-- See Note [Multi Cradle Dependency Info]
544556
type DependencyInfo = Map.Map FilePath (Maybe UTCTime)
545557
type HieMap = Map.Map (Maybe FilePath) (HscEnv, [RawComponentInfo])
558+
-- | Maps a "hie.yaml" location to all its Target Filepaths and options.
546559
type FlagsMap = Map.Map (Maybe FilePath) (HM.HashMap NormalizedFilePath (IdeResult HscEnvEq, DependencyInfo))
560+
-- | Maps a Filepath to its respective "hie.yaml" location.
561+
-- It aims to be the reverse of 'FlagsMap'.
562+
type FilesMap = HM.HashMap NormalizedFilePath (Maybe FilePath)
547563

548564
-- This is pristine information about a component
549565
data RawComponentInfo = RawComponentInfo

0 commit comments

Comments
 (0)