Skip to content

Commit a02f495

Browse files
committed
apply feedbacks
1 parent c969332 commit a02f495

File tree

3 files changed

+48
-33
lines changed

3 files changed

+48
-33
lines changed

ghcide/src/Development/IDE/Core/OfInterest.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import Control.Monad.Trans.Maybe
3232
import qualified Data.ByteString.Lazy as LBS
3333
import Data.List.Extra (nubOrd)
3434
import Data.Maybe (catMaybes)
35+
import Development.IDE.Core.ProgressReporting
3536
import Development.IDE.Core.RuleTypes
3637
import Development.IDE.Core.Shake
3738
import Development.IDE.Import.DependencyInformation
@@ -95,8 +96,8 @@ modifyFilesOfInterest state f = do
9596
kick :: Action ()
9697
kick = do
9798
files <- HashMap.keys <$> getFilesOfInterest
98-
ShakeExtras{progressUpdate} <- getShakeExtras
99-
liftIO $ progressUpdate KickStarted
99+
ShakeExtras{progress} <- getShakeExtras
100+
liftIO $ progressUpdate progress KickStarted
100101

101102
-- Update the exports map for FOIs
102103
results <- uses GenerateCore files <* uses GetHieAst files
@@ -116,4 +117,4 @@ kick = do
116117
!exportsMap'' = maybe mempty createExportsMap ifaces
117118
void $ liftIO $ modifyVar' exportsMap $ (exportsMap'' <>) . (exportsMap' <>)
118119

119-
liftIO $ progressUpdate KickCompleted
120+
liftIO $ progressUpdate progress KickCompleted

ghcide/src/Development/IDE/Core/ProgressReporting.hs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ noProgressReporting = return $ ProgressReporting
5353

5454
-- | A 'ProgressReporting' that sends the WorkDone Begin and End notifications
5555
-- synchronously. Progress notifications are sent from a sampling thread.
56+
--
57+
-- This 'ProgressReporting' is currently used only in tests.
5658
directProgressReporting
57-
:: Double -- ^ sampling rate
59+
:: Seconds -- ^ sampling rate
5860
-> Maybe (LSP.LanguageContextEnv config)
5961
-> ProgressReportingStyle
6062
-> IO ProgressReporting
@@ -64,8 +66,11 @@ directProgressReporting sample env style = do
6466

6567
let progressUpdate KickStarted = do
6668
u <- newProgressToken
67-
writeIORef st (Just u)
68-
mRunLspT env $ start u
69+
mRunLspT env $ do
70+
ready <- create u
71+
for_ ready $ \_ -> do
72+
start u
73+
liftIO $ writeIORef st (Just u)
6974
progressUpdate KickCompleted = do
7075
mbToken <- atomicModifyIORef st (Nothing,)
7176
for_ mbToken $ \u ->
@@ -78,17 +83,17 @@ directProgressReporting sample env style = do
7883
f file shift = atomicModifyIORef'_ inProgressVar $
7984
HMap.insertWith (\_ x -> shift x) file (shift 0)
8085

81-
progressLoop :: Double -> LSP.LspM a ()
86+
progressLoop :: Seconds -> LSP.LspM a ()
8287
progressLoop prev = do
8388
mbToken <- liftIO $ readIORef st
84-
case mbToken of
89+
next <- case mbToken of
8590
Nothing ->
86-
liftIO (sleep sample) >> progressLoop 0
91+
pure 0
8792
Just t -> do
8893
current <- liftIO $ readIORef inProgressVar
89-
prev <- progress style prev current t
90-
liftIO $ sleep sample
91-
progressLoop prev
94+
progress style prev current t
95+
liftIO $ sleep sample
96+
progressLoop next
9297

9398
progressThread <- async $ mRunLspT env $ progressLoop 0
9499
let progressStop = cancel progressThread
@@ -100,7 +105,7 @@ directProgressReporting sample env style = do
100105
-- before the end of the grace period).
101106
-- Avoid using in tests where progress notifications are used to assert invariants.
102107
delayedProgressReporting
103-
:: Double -- ^ sampling rate, also used as grace period before Begin
108+
:: Seconds -- ^ sampling rate, also used as grace period before Begin
104109
-> Maybe (LSP.LanguageContextEnv c)
105110
-> ProgressReportingStyle
106111
-> IO ProgressReporting
@@ -121,6 +126,9 @@ delayedProgressReporting sample lspEnv style = do
121126
-- And two transitions, modelled by 'ProgressEvent':
122127
-- 1. KickCompleted - transitions from Reporting into Idle
123128
-- 2. KickStarted - transitions from Idle into Reporting
129+
-- When transitioning from Idle to Reporting a new async is spawned that
130+
-- sends progress updates in a loop. The async is cancelled when transitioning
131+
-- from Reporting to Idle.
124132
progressThread mostRecentProgressEvent inProgress = progressLoopIdle
125133
where
126134
progressLoopIdle = do
@@ -147,10 +155,10 @@ delayedProgressReporting sample lspEnv style = do
147155
lspShakeProgress style inProgress = do
148156
u <- liftIO newProgressToken
149157

150-
void $ LSP.sendRequest LSP.SWindowWorkDoneProgressCreate
151-
LSP.WorkDoneProgressCreateParams { _token = u } $ const (pure ())
158+
ready <- create u
152159

153-
bracket_ (start u) (stop u) (loop u 0)
160+
for_ ready $ \_ ->
161+
bracket_ (start u) (stop u) (loop u 0)
154162
where
155163
loop id prev = do
156164
liftIO $ sleep sample
@@ -167,6 +175,16 @@ delayedProgressReporting sample lspEnv style = do
167175
newProgressToken :: IO ProgressToken
168176
newProgressToken = ProgressTextToken . T.pack . show . hashUnique <$> liftIO newUnique
169177

178+
create
179+
:: LSP.MonadLsp config f
180+
=> ProgressToken
181+
-> f (Either ResponseError Empty)
182+
create u = do
183+
b <- liftIO newBarrier
184+
_ <- LSP.sendRequest LSP.SWindowWorkDoneProgressCreate
185+
LSP.WorkDoneProgressCreateParams { _token = u }
186+
(liftIO . signalBarrier b)
187+
liftIO $ waitBarrier b
170188

171189
start :: LSP.MonadLsp config f => ProgressToken -> f ()
172190
start id = LSP.sendNotification LSP.SProgress $
@@ -189,7 +207,7 @@ stop id = LSP.sendNotification LSP.SProgress
189207
}
190208

191209
progress :: (LSP.MonadLsp config f) =>
192-
ProgressReportingStyle -> Double -> HashMap NormalizedFilePath Int -> ProgressToken -> f Double
210+
ProgressReportingStyle -> Seconds -> HashMap NormalizedFilePath Int -> ProgressToken -> f Seconds
193211
progress style prev current id = do
194212
let done = length $ filter (== 0) $ HMap.elems current
195213
let todo = HMap.size current

ghcide/src/Development/IDE/Core/Shake.hs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,7 @@ data ShakeExtras = ShakeExtras
183183
-- positions in a version of that document to positions in the latest version
184184
-- First mapping is delta from previous version and second one is an
185185
-- accumlation of all previous mappings.
186-
,inProgress :: forall a . NormalizedFilePath -> Action a -> Action a
187-
-- ^ Report progress for a rule
188-
,progressUpdate :: ProgressEvent -> IO ()
186+
,progress :: ProgressReporting
189187
,ideTesting :: IdeTesting
190188
-- ^ Whether to enable additional lsp messages used by the test suite for checking invariants
191189
,restartShakeSession :: [DelayedAction ()] -> IO ()
@@ -378,12 +376,11 @@ newtype ShakeSession = ShakeSession
378376
-- | A Shake database plus persistent store. Can be thought of as storing
379377
-- mappings from @(FilePath, k)@ to @RuleResult k@.
380378
data IdeState = IdeState
381-
{shakeDb :: ShakeDatabase
382-
,shakeSession :: MVar ShakeSession
383-
,shakeClose :: IO ()
384-
,shakeExtras :: ShakeExtras
385-
,shakeDatabaseProfile :: ShakeDatabase -> IO (Maybe FilePath)
386-
,stopProgressReporting :: IO ()
379+
{shakeDb :: ShakeDatabase
380+
,shakeSession :: MVar ShakeSession
381+
,shakeClose :: IO ()
382+
,shakeExtras :: ShakeExtras
383+
,shakeDatabaseProfile :: ShakeDatabase -> IO (Maybe FilePath)
387384
}
388385

389386

@@ -473,7 +470,7 @@ shakeOpen lspEnv defaultConfig logger debouncer
473470

474471
us <- mkSplitUniqSupply 'r'
475472
ideNc <- newIORef (initNameCache us knownKeyNames)
476-
(shakeExtras, stopProgressReporting) <- do
473+
shakeExtras <- do
477474
globals <- newVar HMap.empty
478475
state <- newVar HMap.empty
479476
diagnostics <- newVar mempty
@@ -489,7 +486,7 @@ shakeOpen lspEnv defaultConfig logger debouncer
489486
let hiedbWriter = HieDbWriter{..}
490487
exportsMap <- newVar mempty
491488

492-
ProgressReporting{..} <-
489+
progress <-
493490
if reportProgress
494491
then (if testing
495492
then directProgressReporting
@@ -499,9 +496,8 @@ shakeOpen lspEnv defaultConfig logger debouncer
499496
actionQueue <- newQueue
500497

501498
let clientCapabilities = maybe def LSP.resClientCapabilities lspEnv
502-
extras = ShakeExtras{..}
503499

504-
pure (extras, progressStop)
500+
pure ShakeExtras{..}
505501
(shakeDbM, shakeClose) <-
506502
shakeOpenDatabase
507503
opts { shakeExtra = newShakeExtra shakeExtras }
@@ -534,7 +530,7 @@ shakeShut IdeState{..} = withMVar shakeSession $ \runner -> do
534530
-- request so we first abort that.
535531
void $ cancelShakeSession runner
536532
shakeClose
537-
stopProgressReporting
533+
progressStop $ progress shakeExtras
538534

539535

540536
-- | This is a variant of withMVar where the first argument is run unmasked and if it throws
@@ -849,9 +845,9 @@ defineEarlyCutoff'
849845
-> Action (Maybe BS.ByteString, IdeResult v)
850846
-> Action (RunResult (A (RuleResult k)))
851847
defineEarlyCutoff' doDiagnostics key file old mode action = do
852-
extras@ShakeExtras{state, inProgress, logger} <- getShakeExtras
848+
extras@ShakeExtras{state, progress, logger} <- getShakeExtras
853849
options <- getIdeOptions
854-
(if optSkipProgress options key then id else inProgress file) $ do
850+
(if optSkipProgress options key then id else inProgress progress file) $ do
855851
val <- case old of
856852
Just old | mode == RunDependenciesSame -> do
857853
v <- liftIO $ getValues state key file

0 commit comments

Comments
 (0)