Skip to content

Commit 0cc888b

Browse files
committed
cleanup
1 parent ed74540 commit 0cc888b

File tree

3 files changed

+40
-26
lines changed

3 files changed

+40
-26
lines changed

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

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ import Control.Concurrent.STM.Stats (atomicallyNamed)
2121
import Control.DeepSeq (force)
2222
import Control.Exception
2323
import Control.Monad.IO.Class
24+
import Control.Monad.RWS (MonadReader (ask),
25+
asks)
2426
import Control.Monad.Trans.Class
25-
import Control.Monad.Trans.Reader
2627
import Data.Foldable (toList)
2728
import Data.Functor.Identity
2829
import Data.IORef
@@ -41,13 +42,13 @@ type ShakeValue a = (Show a, Typeable a, Eq a, Hashable a, NFData a)
4142
-- | Always rerun this rule when dirty, regardless of the dependencies.
4243
alwaysRerun :: Action ()
4344
alwaysRerun = do
44-
ref <- Action $ asks actionDeps
45+
ref <- asks actionDeps
4546
liftIO $ modifyIORef' ref (AlwaysRerunDeps mempty <>)
4647

4748
parallel :: [Action a] -> Action [Either SomeException a]
4849
parallel [] = return []
4950
parallel xs = do
50-
a <- Action ask
51+
a <- ask
5152
deps <- liftIO $ readIORef $ actionDeps a
5253
case deps of
5354
UnknownDeps ->
@@ -61,15 +62,15 @@ parallel xs = do
6162
-- non-blocking version of runActionInDb
6263
runActionInDbCb :: (a -> String) -> (a -> Action result) -> STM a -> (Either SomeException result -> IO ()) -> Action a
6364
runActionInDbCb getTitle work getAct handler = do
64-
a <- Action ask
65+
a <- ask
6566
liftIO $ atomicallyNamed "action queue - pop" $ do
6667
act <- getAct
6768
runInDataBase (getTitle act) (actionDatabase a) [(ignoreState a $ work act, handler)]
6869
return act
6970

7071
runActionInDb :: String -> [Action a] -> Action [Either SomeException a]
7172
runActionInDb title acts = do
72-
a <- Action ask
73+
a <- ask
7374
xs <- mapM (\x -> do
7475
barrier <- newEmptyTMVarIO
7576
return (x, barrier)) acts
@@ -81,7 +82,7 @@ runActionInDb title acts = do
8182
ignoreState :: SAction -> Action b -> IO b
8283
ignoreState a x = do
8384
ref <- newIORef mempty
84-
runReaderT (fromAction x) a{actionDeps=ref}
85+
runActionMonad x a{actionDeps=ref}
8586

8687
isAsyncException :: SomeException -> Bool
8788
isAsyncException e
@@ -95,8 +96,8 @@ isAsyncException e
9596

9697
actionCatch :: Exception e => Action a -> (e -> Action a) -> Action a
9798
actionCatch a b = do
98-
v <- Action ask
99-
Action $ lift $ catchJust f (runReaderT (fromAction a) v) (\x -> runReaderT (fromAction (b x)) v)
99+
v <- ask
100+
liftIO $ catchJust f (runActionMonad a v) (\x -> runActionMonad (b x) v)
100101
where
101102
-- Catch only catches exceptions that were caused by this code, not those that
102103
-- are a result of program termination
@@ -105,41 +106,41 @@ actionCatch a b = do
105106

106107
actionBracket :: IO a -> (a -> IO b) -> (a -> Action c) -> Action c
107108
actionBracket a b c = do
108-
v <- Action ask
109-
Action $ lift $ bracket a b (\x -> runReaderT (fromAction (c x)) v)
109+
v <- ask
110+
liftIO $ bracket a b (\x -> runActionMonad (c x) v)
110111

111112
actionFinally :: Action a -> IO b -> Action a
112113
actionFinally a b = do
113114
v <- Action ask
114-
Action $ lift $ finally (runReaderT (fromAction a) v) b
115+
Action $ lift $ finally (runActionMonad a v) b
115116

116117
apply1 :: (RuleResult key ~ value, ShakeValue key, Typeable value) => key -> Action value
117118
apply1 k = runIdentity <$> apply (Identity k)
118119

119120
apply :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value)
120121
apply ks = do
121-
db <- Action $ asks actionDatabase
122-
stack <- Action $ asks actionStack
122+
db <- asks actionDatabase
123+
stack <- asks actionStack
123124
pk <- getActionKey
124125
(is, vs) <- liftIO $ build pk db stack ks
125-
ref <- Action $ asks actionDeps
126+
ref <- asks actionDeps
126127
let !ks = force $ fromListKeySet $ toList is
127128
liftIO $ modifyIORef' ref (ResultDeps [ks] <>)
128129
pure vs
129130

130131
-- | Evaluate a list of keys without recording any dependencies.
131132
applyWithoutDependency :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value)
132133
applyWithoutDependency ks = do
133-
db <- Action $ asks actionDatabase
134-
stack <- Action $ asks actionStack
134+
db <- asks actionDatabase
135+
stack <- asks actionStack
135136
pk <- getActionKey
136137
(_, vs) <- liftIO $ build pk db stack ks
137138
pure vs
138139

139140
runActions :: Key -> Database -> [Action a] -> IO [Either SomeException a]
140141
runActions pk db xs = do
141142
deps <- newIORef mempty
142-
runReaderT (fromAction $ parallel xs) $ SAction pk db deps emptyStack
143+
runActionMonad (parallel xs) $ SAction pk db deps emptyStack
143144

144145
-- | Returns the set of dirty keys annotated with their age (in # of builds)
145146
getDirtySet :: Action [(Key, Int)]

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import Control.Monad (forM, forM_, forever,
1111
unless, when)
1212
import Control.Monad.Catch
1313
import Control.Monad.IO.Class
14-
import Control.Monad.Trans.Reader
14+
import Control.Monad.RWS (MonadReader (local), asks)
15+
import Control.Monad.Trans.Reader (ReaderT (..))
1516
import Data.Aeson (FromJSON, ToJSON)
1617
import Data.Bifunctor (second)
1718
import qualified Data.ByteString as BS
@@ -88,7 +89,10 @@ data SRules = SRules {
8889
-- 'Development.IDE.Graph.Internal.Action.actionCatch'. In particular, it is
8990
-- permissible to use the 'MonadFail' instance, which will lead to an 'IOException'.
9091
newtype Action a = Action {fromAction :: ReaderT SAction IO a}
91-
deriving newtype (Monad, Applicative, Functor, MonadIO, MonadFail, MonadThrow, MonadCatch, MonadMask, MonadUnliftIO)
92+
deriving newtype (Monad, Applicative, Functor, MonadIO, MonadFail, MonadThrow, MonadCatch, MonadMask, MonadUnliftIO, MonadReader SAction)
93+
94+
runActionMonad :: Action a -> SAction -> IO a
95+
runActionMonad (Action r) s = runReaderT r s
9296

9397
data SAction = SAction {
9498
actionKey :: !Key,
@@ -98,14 +102,13 @@ data SAction = SAction {
98102
}
99103

100104
getDatabase :: Action Database
101-
getDatabase = Action $ asks actionDatabase
105+
getDatabase = asks actionDatabase
102106

103107
getActionKey :: Action Key
104-
getActionKey = Action $ asks actionKey
108+
getActionKey = asks actionKey
105109

106110
setActionKey :: Key -> Action a -> Action a
107-
setActionKey k (Action act) = Action $ do
108-
local (\s' -> s'{actionKey = k}) act
111+
setActionKey k act = local (\s' -> s'{actionKey = k}) act
109112

110113
-- | waitForDatabaseRunningKeysAction waits for all keys in the database to finish running.
111114
-- waitForDatabaseRunningKeysAction :: Action ()

hls-graph/src/Development/IDE/WorkerThread.hs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ module Development.IDE.WorkerThread
2525
tryReadTaskQueue,
2626
withWorkerQueueSimpleRight,
2727
submitWorkAtHead,
28-
awaitRunInThread
28+
awaitRunInThread,
29+
withAsyncs
2930
) where
3031

3132
import Control.Concurrent.Async (withAsync)
@@ -81,8 +82,12 @@ withWorkerQueueSimple log title = withWorkerQueue log title id
8182

8283
withWorkerQueueSimpleRight :: Logger -> T.Text -> ContT () IO (TaskQueue (Either Dynamic (IO ())))
8384
withWorkerQueueSimpleRight log title = withWorkerQueue log title $ eitherWorker (const $ return ()) id
85+
86+
8487
withWorkerQueue :: Logger -> T.Text -> (t -> IO ()) -> ContT () IO (TaskQueue t)
85-
withWorkerQueue log title workerAction = ContT $ \mainAction -> do
88+
withWorkerQueue = withWorkersQueue 1
89+
withWorkersQueue :: Int -> Logger -> T.Text -> (t -> IO ()) -> ContT () IO (TaskQueue t)
90+
withWorkersQueue n log title workerAction = ContT $ \mainAction -> do
8691
tid <- myThreadId
8792
log (LogMainThreadId title tid)
8893
q <- newTaskQueueIO
@@ -94,7 +99,7 @@ withWorkerQueue log title workerAction = ContT $ \mainAction -> do
9499
-- If 'cancel' does interrupt the thread (e.g., while blocked in STM or in a cooperative job),
95100
-- the thread exits immediately and never checks the TMVar; in such cases, the stop flag is redundant.
96101
b <- newEmptyTMVarIO
97-
withAsync (writerThread q b) $ \_ -> do
102+
withAsyncs (replicate n (writerThread q b)) $ do
98103
mainAction q
99104
-- if we want to debug the exact location the worker swallows an async exception, we can
100105
-- temporarily comment out the `finally` clause.
@@ -121,6 +126,11 @@ withWorkerQueue log title workerAction = ContT $ \mainAction -> do
121126
log $ LogSingleWorkEnded title
122127
writerThread q b
123128

129+
withAsyncs :: [IO ()] -> IO () -> IO ()
130+
withAsyncs ios mainAction = go ios
131+
where
132+
go [] = mainAction
133+
go (x:xs) = withAsync x $ \_ -> go xs
124134

125135
-- | 'awaitRunInThread' queues up an 'IO' action to be run by a worker thread,
126136
-- and then blocks until the result is computed. If the action throws an

0 commit comments

Comments
 (0)