Skip to content
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

Improve async runtime scaling #946

Merged
merged 18 commits into from
Aug 23, 2023
Merged
Prev Previous commit
Next Next commit
Stub: async scheduler
  • Loading branch information
jaspervdj committed Aug 4, 2022
commit 8266a735ac602b5d9354fc0e8c189ce188a55de0
48 changes: 24 additions & 24 deletions lib/Hakyll/Core/Runtime.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Control.Monad.Trans (liftIO)
import Data.Foldable (for_, traverse_)
import Data.IORef (IORef)
import qualified Data.IORef as IORef
import Data.List (foldl')
import Data.List (foldl', intercalate)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
Expand Down Expand Up @@ -211,11 +211,15 @@ data SchedulerStep
schedulerPop :: Scheduler -> (Scheduler, SchedulerStep)
schedulerPop scheduler@Scheduler {..} = case Seq.viewl schedulerQueue of
Seq.EmptyL
| Set.null schedulerWorking -> (scheduler, SchedulerFinish)
| otherwise ->
| not $ Set.null schedulerWorking ->
( scheduler {schedulerStarved = schedulerStarved + 1}
, SchedulerStarve
)
| not $ Set.null schedulerBlocked ->
let msg = "Possible dependency cycle in: " <>
intercalate ", " (show <$> Set.toList schedulerBlocked) in
SchedulerError <$ schedulerError Nothing msg scheduler
| otherwise -> (scheduler, SchedulerFinish)
x Seq.:< xs
| x `Set.member` schedulerDone ->
schedulerPop scheduler {schedulerQueue = xs}
Expand All @@ -224,12 +228,8 @@ schedulerPop scheduler@Scheduler {..} = case Seq.viewl schedulerQueue of
| x `Set.member` schedulerBlocked ->
schedulerPop scheduler {schedulerQueue = xs}
| otherwise -> case Map.lookup x schedulerTodo of
Nothing ->
( scheduler
{ schedulerErrors = (Just x, "Compiler not found") : schedulerErrors
}
, SchedulerError
)
Nothing -> SchedulerError <$
schedulerError (Just x) "Compiler not found" scheduler
Just c ->
( scheduler
{ schedulerQueue = xs
Expand Down Expand Up @@ -333,7 +333,7 @@ build mode = do
logger <- runtimeLogger <$> ask
Logger.header logger "Checking for out-of-date items"
schedulerRef <- runtimeScheduler <$> ask
scheduleOutOfDate2
scheduleOutOfDate
case mode of
RunModeNormal -> do
Logger.header logger "Compiling"
Expand All @@ -349,11 +349,11 @@ build mode = do


--------------------------------------------------------------------------------
scheduleOutOfDate2 :: ReaderT RuntimeRead IO ()
scheduleOutOfDate2 = do
logger <- runtimeLogger <$> ask
provider <- runtimeProvider <$> ask
universe <- runtimeUniverse <$> ask
scheduleOutOfDate :: ReaderT RuntimeRead IO ()
scheduleOutOfDate = do
logger <- runtimeLogger <$> ask
provider <- runtimeProvider <$> ask
universe <- runtimeUniverse <$> ask
schedulerRef <- runtimeScheduler <$> ask
let modified = Set.filter (resourceModified provider) (Map.keysSet universe)
msgs <- liftIO . IORef.atomicModifyIORef' schedulerRef $
Expand All @@ -367,13 +367,14 @@ scheduleOutOfDate2 = do
pickAndChase :: ReaderT RuntimeRead IO ()
pickAndChase = do
scheduler <- runtimeScheduler <$> ask
pop <- liftIO . IORef.atomicModifyIORef' scheduler $ schedulerPop
let go SchedulerFinish = pure ()
go SchedulerError = pure ()
go (SchedulerWork i c _) = work i c >>= go
go SchedulerStarve =
liftIO . IORef.atomicModifyIORef' scheduler $
schedulerError Nothing "Starved, possible dependency cycle?"
pop <- liftIO . IORef.atomicModifyIORef' scheduler $ schedulerPop
go pop
where
go SchedulerFinish = pure ()
go SchedulerStarve = pure ()
go SchedulerError = pure ()
go (SchedulerWork i c _) = work i c >>= go


--------------------------------------------------------------------------------
Expand All @@ -388,9 +389,8 @@ pickAndChaseAsync = do
signal <- MVar.newEmptyMVar

let spawnN :: Int -> IO ()
spawnN n = replicateM_ n $ forkIO $ do
pop <- IORef.atomicModifyIORef' scheduler $ schedulerPop
go pop
spawnN n = replicateM_ n $ forkIO $
IORef.atomicModifyIORef' scheduler schedulerPop >>= go

go :: SchedulerStep -> IO ()
go step = case step of
Expand Down
2 changes: 1 addition & 1 deletion tests/TestSuite/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fromAssertions :: String -- ^ Name
-> [Assertion] -- ^ Cases
-> [TestTree] -- ^ Result tests
fromAssertions name =
zipWith testCase [printf "[%2d] %s" n name | n <- [1 :: Int ..]]
zipWith testCase [printf "%02d_%s" n name | n <- [1 :: Int ..]]


--------------------------------------------------------------------------------
Expand Down