Skip to content

Reimplement shake (continued) #2060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Sep 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
3681db8
Rewrite hls-graph to not use the Shake code
ndmitchell Apr 19, 2021
575a582
redundant import
pepeiborra Aug 1, 2021
f351525
Fix the bug
pepeiborra Aug 1, 2021
c96c005
add comments and format imports
pepeiborra Aug 1, 2021
3a13008
Fix another bug
pepeiborra Aug 2, 2021
2aac6c9
fix locking in incDatabase
pepeiborra Aug 3, 2021
18e6765
avoid calling withNumCapabilities on every build
pepeiborra Aug 6, 2021
8cb1754
faster cleanup
pepeiborra Aug 19, 2021
0f6f94c
implement reverse deps
pepeiborra Aug 2, 2021
557c3b4
--conservative-change-tracking
pepeiborra Aug 2, 2021
e20d482
Avoid grabbing the db lock when updating reverse deps
pepeiborra Aug 18, 2021
53ff99d
update reverse deps asynchronously
pepeiborra Aug 18, 2021
f4a8be8
Profiling graph builds
pepeiborra Aug 13, 2021
6b0ea6e
extend up profiling to record visiting steps
pepeiborra Aug 17, 2021
d9ced37
include dirty set in profiles
pepeiborra Aug 22, 2021
0d1d3c9
actionFork
pepeiborra Aug 8, 2021
30d15f7
avoid spawning threads for simple lookups
pepeiborra Aug 18, 2021
fd55f22
Fix a flaky test
pepeiborra Aug 22, 2021
678b817
record changes to GetKnownTargets
pepeiborra Aug 23, 2021
31b7203
Readme for hls-graph
pepeiborra Aug 23, 2021
ca93ba5
Bump version numbers
pepeiborra Aug 23, 2021
8a6bef3
Drop dependency on Shake
pepeiborra Aug 23, 2021
6070edc
explain why we restart a Shake session
pepeiborra Aug 25, 2021
e2b7782
clean up Internal.Database
pepeiborra Aug 25, 2021
2c263b7
add a new benchmark example cabal-1module
pepeiborra Aug 25, 2021
6ebcea6
Fix masking and further reduce threading
pepeiborra Aug 25, 2021
204cd53
Trace aborted rule evaluations
pepeiborra Aug 27, 2021
58dfe17
Fix code actions after cradle edit experiment
pepeiborra Aug 27, 2021
138ec1c
Avoid spawning threads for build rules with 1 or fewer deps
pepeiborra Aug 27, 2021
58507f8
simplify a test
pepeiborra Aug 28, 2021
411c2a3
hlint
pepeiborra Sep 2, 2021
01a3d31
Add a test for off-editor changes
pepeiborra Sep 11, 2021
23d5b54
Fix flaky tests
pepeiborra Sep 18, 2021
4817514
fix incomplete pattern match in Tactics test suite
pepeiborra Sep 19, 2021
e2c86f7
Fix flaky tests
pepeiborra Sep 19, 2021
4d0cc73
attempt to fix tactics test suite in Windows
pepeiborra Sep 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion ghcide/bench/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,35 @@ examples:
- Distribution/Simple.hs
- Distribution/Types/Module.hs
extra-args: [] # extra ghcide command line args
- name: cabal-1module
package: Cabal
version: 3.0.0.0
modules:
- Distribution/Simple.hs
- name: cabal-conservative
package: Cabal
version: 3.0.0.0
modules:
- Distribution/Simple.hs
- Distribution/Types/Module.hs
extra-args: # extra ghcide command line args
- --conservative-change-tracking
# Small-sized project with TH
- name: lsp-types
package: lsp-types
version: 1.0.0.1
modules:
- src/Language/LSP/VFS.hs
- src/Language/LSP/Types/Lens.hs
extra-args: [] # extra ghcide command line args
- name: lsp-types-conservative
package: lsp-types
version: 1.0.0.1
modules:
- src/Language/LSP/VFS.hs
- src/Language/LSP/Types/Lens.hs
extra-args:
- --conservative-change-tracking
# Small-sized project with TH
# Small but heavily multi-component example
# Disabled as it is far to slow. hie-bios >0.7.2 should help
# - name: HLS
Expand Down
39 changes: 22 additions & 17 deletions ghcide/bench/lib/Experiments.hs
Original file line number Diff line number Diff line change
Expand Up @@ -152,21 +152,22 @@ experiments =
benchWithSetup
"code actions after cradle edit"
( \docs -> do
unless (any (isJust . identifierP) docs) $
error "None of the example modules is suitable for this experiment"
forM_ docs $ \DocumentPositions{..} ->
forM_ identifierP $ \p -> changeDoc doc [charEdit p]
forM_ docs $ \DocumentPositions{..} -> do
forM identifierP $ \p -> do
changeDoc doc [charEdit p]
waitForProgressStart
void waitForBuildQueue
)
( \docs -> do
hieYamlUri <- getDocUri "hie.yaml"
liftIO $ appendFile (fromJust $ uriToFilePath hieYamlUri) "##\n"
sendNotification SWorkspaceDidChangeWatchedFiles $ DidChangeWatchedFilesParams $
List [ FileEvent hieYamlUri FcChanged ]
forM_ docs $ \DocumentPositions{..} -> do
changeDoc doc [charEdit stringLiteralP]
waitForProgressStart
waitForProgressStart
waitForProgressStart
waitForProgressStart -- the Session logic restarts a second time
waitForProgressDone
not . null . catMaybes <$> forM docs (\DocumentPositions{..} -> do
not . all null . catMaybes <$> forM docs (\DocumentPositions{..} -> do
forM identifierP $ \p ->
getCodeActions doc (Range p p))
),
Expand Down Expand Up @@ -421,6 +422,17 @@ waitForProgressDone = loop
done <- null <$> getIncompleteProgressSessions
unless done loop

-- | Wait for the build queue to be empty
waitForBuildQueue :: Session Seconds
waitForBuildQueue = do
let m = SCustomMethod "test"
waitId <- sendRequest m (toJSON WaitForShakeQueue)
(td, resp) <- duration $ skipManyTill anyMessage $ responseForId m waitId
case resp of
ResponseMessage{_result=Right Null} -> return td
-- assume a ghcide binary lacking the WaitForShakeQueue method
_ -> return 0

runBench ::
(?config :: Config) =>
(Session BenchRun -> IO BenchRun) ->
Expand Down Expand Up @@ -451,15 +463,8 @@ runBench runSess b = handleAny (\e -> print e >> return badRun)
else do
output (showDuration t)
-- Wait for the delayed actions to finish
let m = SCustomMethod "test"
waitId <- sendRequest m (toJSON WaitForShakeQueue)
(td, resp) <- duration $ skipManyTill anyMessage $ responseForId m waitId
case resp of
ResponseMessage{_result=Right Null} -> do
loop (userWaits+t) (delayedWork+td) (n -1)
_ ->
-- Assume a ghcide build lacking the WaitForShakeQueue command
loop (userWaits+t) delayedWork (n -1)
td <- waitForBuildQueue
loop (userWaits+t) (delayedWork+td) (n -1)

(runExperiment, result) <- duration $ loop 0 0 samples
let success = isJust result
Expand Down
20 changes: 11 additions & 9 deletions ghcide/exe/Arguments.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import Ide.Types (IdePlugins)
import Options.Applicative

data Arguments = Arguments
{argsCwd :: Maybe FilePath
,argsVersion :: Bool
,argsShakeProfiling :: Maybe FilePath
,argsOTMemoryProfiling :: Bool
,argsTesting :: Bool
,argsDisableKick :: Bool
,argsThreads :: Int
,argsVerbose :: Bool
,argsCommand :: Command
{argsCwd :: Maybe FilePath
,argsVersion :: Bool
,argsShakeProfiling :: Maybe FilePath
,argsOTMemoryProfiling :: Bool
,argsTesting :: Bool
,argsDisableKick :: Bool
,argsThreads :: Int
,argsVerbose :: Bool
,argsCommand :: Command
,argsConservativeChangeTracking :: Bool
}

getArguments :: IdePlugins IdeState -> IO Arguments
Expand All @@ -38,6 +39,7 @@ arguments plugins = Arguments
<*> option auto (short 'j' <> help "Number of threads (0: automatic)" <> metavar "NUM" <> value 0 <> showDefault)
<*> switch (short 'd' <> long "verbose" <> help "Include internal events in logging output")
<*> (commandP plugins <|> lspCommand <|> checkCommand)
<*> switch (long "conservative-change-tracking" <> help "disable reactive change tracking (for testing/debugging)")
where
checkCommand = Check <$> many (argument str (metavar "FILES/DIRS..."))
lspCommand = LSP <$ flag' True (long "lsp" <> help "Start talking to an LSP client")
3 changes: 3 additions & 0 deletions ghcide/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ main = do
then Test.plugin
else mempty

,Main.argsThreads = case argsThreads of 0 -> Nothing ; i -> Just (fromIntegral i)

,Main.argsIdeOptions = \config sessionLoader ->
let defOptions = defaultIdeOptions sessionLoader
in defOptions
Expand All @@ -80,5 +82,6 @@ main = do
, optShakeOptions = (optShakeOptions defOptions){shakeThreads = argsThreads}
, optCheckParents = pure $ checkParents config
, optCheckProject = pure $ checkProject config
, optRunSubset = not argsConservativeChangeTracking
}
}
4 changes: 3 additions & 1 deletion ghcide/ghcide.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ library
dependent-map,
dependent-sum,
dlist,
exceptions,
-- we can't use >= 1.7.10 while we have to use hlint == 3.2.*
extra >= 1.7.4 && < 1.7.10,
fuzzy,
Expand Down Expand Up @@ -76,7 +77,7 @@ library
rope-utf16-splay,
safe,
safe-exceptions,
hls-graph ^>= 1.4,
hls-graph ^>= 1.5,
sorted-list,
sqlite-simple,
stm,
Expand Down Expand Up @@ -269,6 +270,7 @@ benchmark benchHist
directory,
extra,
filepath,
lens,
optparse-applicative,
shake,
text,
Expand Down
4 changes: 2 additions & 2 deletions ghcide/session-loader/Development/IDE/Session.hs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do

IdeOptions{ optTesting = IdeTesting optTesting
, optCheckProject = getCheckProject
, optModifyDynFlags
, optExtensions
} <- getIdeOptions

Expand All @@ -264,6 +263,7 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
TargetModule _ -> do
found <- filterM (IO.doesFileExist . fromNormalizedFilePath) targetLocations
return (targetTarget, found)
recordDirtyKeys extras GetKnownTargets [emptyFilePath]
modifyVarIO' knownTargetsVar $ traverseHashed $ \known -> do
let known' = HM.unionWith (<>) known $ HM.fromList $ map (second Set.fromList) knownTargets
when (known /= known') $
Expand Down Expand Up @@ -390,7 +390,7 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do

-- Invalidate all the existing GhcSession build nodes by restarting the Shake session
invalidateShakeCache
restartShakeSession []
restartShakeSession "new component" []

-- Typecheck all files in the project on startup
checkProject <- getCheckProject
Expand Down
9 changes: 4 additions & 5 deletions ghcide/src/Development/IDE/Core/FileStore.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import Development.IDE.Import.DependencyInformation
import Development.IDE.Types.Diagnostics
import Development.IDE.Types.Location
import Development.IDE.Types.Options
import Development.IDE.Types.Shake (SomeShakeValue)
import HieDb.Create (deleteMissingRealFiles)
import Ide.Plugin.Config (CheckParents (..),
Config)
Expand Down Expand Up @@ -271,7 +270,7 @@ setFileModified state saved nfp = do
when (isJust setVirtualFileContents) $
fail "setFileModified can't be called on this type of VFSHandle"
recordDirtyKeys (shakeExtras state) GetModificationTime [nfp]
restartShakeSession (shakeExtras state) []
restartShakeSession (shakeExtras state) (fromNormalizedFilePath nfp ++ " (modified)") []
when checkParents $
typecheckParents state nfp

Expand All @@ -294,16 +293,16 @@ typecheckParentsAction nfp = do
-- | Note that some keys have been modified and restart the session
-- Only valid if the virtual file system was initialised by LSP, as that
-- independently tracks which files are modified.
setSomethingModified :: IdeState -> [SomeShakeValue] -> IO ()
setSomethingModified state keys = do
setSomethingModified :: IdeState -> [Key] -> String -> IO ()
setSomethingModified state keys reason = do
VFSHandle{..} <- getIdeGlobalState state
when (isJust setVirtualFileContents) $
fail "setSomethingModified can't be called on this type of VFSHandle"
-- Update database to remove any files that might have been renamed/deleted
atomically $ writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) deleteMissingRealFiles
atomicModifyIORef_ (dirtyKeys $ shakeExtras state) $ \x ->
foldl' (flip HSet.insert) x keys
void $ restartShakeSession (shakeExtras state) []
void $ restartShakeSession (shakeExtras state) reason []

registerFileWatches :: [String] -> LSP.LspT Config IO Bool
registerFileWatches globs = do
Expand Down
Loading