module Development.IDE.Types.Action
( DelayedAction (..),
DelayedActionInternal,
ActionQueue,
newQueue,
pushQueue,
popQueue,
doneQueue,
peekInProgress,
abortQueue,countQueue)
where
import Control.Concurrent.STM
import Data.Hashable (Hashable (..))
import Data.HashSet (HashSet)
import qualified Data.HashSet as Set
import Data.Unique (Unique)
import Development.IDE.Types.Logger
import Development.Shake (Action)
import Numeric.Natural
data DelayedAction a = DelayedAction
{ uniqueID :: Maybe Unique,
actionName :: String,
actionPriority :: Priority,
getAction :: Action a
}
deriving (Functor)
type DelayedActionInternal = DelayedAction ()
instance Eq (DelayedAction a) where
a == b = uniqueID a == uniqueID b
instance Hashable (DelayedAction a) where
hashWithSalt s = hashWithSalt s . uniqueID
instance Show (DelayedAction a) where
show d = "DelayedAction: " ++ actionName d
data ActionQueue = ActionQueue
{ newActions :: TQueue DelayedActionInternal,
inProgress :: TVar (HashSet DelayedActionInternal)
}
newQueue :: IO ActionQueue
newQueue = atomically $ do
newActions <- newTQueue
inProgress <- newTVar mempty
return ActionQueue {..}
pushQueue :: DelayedActionInternal -> ActionQueue -> STM ()
pushQueue act ActionQueue {..} = writeTQueue newActions act
popQueue :: ActionQueue -> STM DelayedActionInternal
popQueue ActionQueue {..} = do
x <- readTQueue newActions
modifyTVar inProgress (Set.insert x)
return x
abortQueue :: DelayedActionInternal -> ActionQueue -> STM ()
abortQueue x ActionQueue {..} = do
qq <- flushTQueue newActions
mapM_ (writeTQueue newActions) (filter (/= x) qq)
modifyTVar inProgress (Set.delete x)
doneQueue :: DelayedActionInternal -> ActionQueue -> STM ()
doneQueue x ActionQueue {..} = do
modifyTVar inProgress (Set.delete x)
countQueue :: ActionQueue -> STM Natural
countQueue ActionQueue{..} = do
backlog <- flushTQueue newActions
mapM_ (writeTQueue newActions) backlog
m <- Set.size <$> readTVar inProgress
return $ fromIntegral $ length backlog + m
peekInProgress :: ActionQueue -> STM [DelayedActionInternal]
peekInProgress ActionQueue {..} = Set.toList <$> readTVar inProgress