Skip to content

Commit 8c25bb5

Browse files
Vladimir Ciobanujustinwoo
authored andcommitted
Limit threads (#127)
* moving * test * fix? * whoops * limitThreads all the things * addressed reviews, still need to ttest * removed two more formatting changes * forgot to rename argument to jobs * signalQSem * should use bracket_, removed the styling changes again * couple of extra spacing causing noise in the diff * and one more
1 parent 68bac74 commit 8c25bb5

File tree

2 files changed

+79
-24
lines changed

2 files changed

+79
-24
lines changed

Makefile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package = psc-package
2+
3+
stack_yaml = STACK_YAML="stack.yaml"
4+
stack = $(stack_yaml) stack
5+
6+
build:
7+
$(stack) build $(package)
8+
9+
build-dirty:
10+
$(stack) build --ghc-options=-fforce-recomp $(package)
11+
12+
run:
13+
$(stack) build --fast && $(stack) exec -- $(package)
14+
15+
install:
16+
$(stack) install
17+
18+
ghci:
19+
$(stack) ghci $(package)
20+
21+
test:
22+
$(stack) test $(package)
23+
24+
test-ghci:
25+
$(stack) ghci $(package):test:$(package)-tests
26+
27+
bench:
28+
$(stack) bench $(package)
29+
30+
ghcid:
31+
$(stack) exec -- ghcid -c "stack ghci $(package) --test --ghci-options='-fobject-code -fno-warn-unused-do-bind'"
32+
33+
dev-deps:
34+
stack install ghcid
35+
36+
.PHONY : build build-dirty run install ghci test test-ghci ghcid dev-deps

app/Main.hs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ module Main where
1111

1212
import qualified Control.Foldl as Foldl
1313
import Control.Concurrent.Async (forConcurrently_, mapConcurrently)
14+
import Control.Concurrent.QSem (newQSem, signalQSem, waitQSem)
15+
import Control.Exception (bracket_)
1416
import qualified Data.Aeson as Aeson
1517
import Data.Aeson.Encode.Pretty
1618
import Data.Either.Combinators (rightToMaybe)
@@ -237,13 +239,18 @@ getTransitiveDeps db deps =
237239
sansPrefix <- T.stripPrefix "purescript-" (runPackageName pkg)
238240
rightToMaybe (mkPackageName sansPrefix)
239241

240-
installImpl :: PackageConfig -> IO ()
241-
installImpl config@PackageConfig{ depends } = do
242+
installImpl :: PackageConfig -> Maybe Int -> IO ()
243+
installImpl config@PackageConfig{ depends } limitJobs = do
242244
getPackageSet config
243245
db <- readPackageSet config
244246
trans <- getTransitiveDeps db depends
245247
echoT ("Installing " <> pack (show (length trans)) <> " packages...")
246-
forConcurrently_ trans . uncurry $ performInstall $ set config
248+
case limitJobs of
249+
Nothing ->
250+
forConcurrently_ trans . uncurry $ performInstall $ set config
251+
Just max' -> do
252+
sem <- newQSem max'
253+
forConcurrently_ trans . uncurry . (\x y z -> bracket_ (waitQSem sem) (signalQSem sem) (performInstall x y z)) $ set config
247254

248255
getPureScriptVersion :: IO Version
249256
getPureScriptVersion = do
@@ -256,8 +263,8 @@ getPureScriptVersion = do
256263
| otherwise -> exitWithErr "Unable to parse output of purs --version"
257264
_ -> exitWithErr "Unexpected output from purs --version"
258265

259-
initialize :: Maybe (Text, Maybe Text) -> IO ()
260-
initialize setAndSource = do
266+
initialize :: Maybe (Text, Maybe Text) -> Maybe Int -> IO ()
267+
initialize setAndSource limitJobs = do
261268
exists <- testfile "psc-package.json"
262269
when exists $ exitWithErr "psc-package.json already exists"
263270
echoT "Initializing new project in current directory"
@@ -281,33 +288,33 @@ initialize setAndSource = do
281288
}
282289

283290
writePackageFile pkg
284-
installImpl pkg
291+
installImpl pkg limitJobs
285292
where
286293
packageNameFromPWD =
287294
either (const untitledPackageName) id . mkPackageName
288295

289-
install :: Maybe String -> IO ()
290-
install pkgName' = do
296+
install :: Maybe String -> Maybe Int -> IO ()
297+
install pkgName' limitJobs = do
291298
pkg <- readPackageFile
292299
case pkgName' of
293300
Nothing -> do
294-
installImpl pkg
301+
installImpl pkg limitJobs
295302
echoT "Install complete"
296303
Just str -> do
297304
pkgName <- packageNameFromString str
298305
let pkg' = pkg { depends = List.nub (pkgName : depends pkg) }
299-
updateAndWritePackageFile pkg'
306+
updateAndWritePackageFile pkg' limitJobs
300307

301-
uninstall :: String -> IO ()
302-
uninstall pkgName' = do
308+
uninstall :: String -> Maybe Int -> IO ()
309+
uninstall pkgName' limitJobs = do
303310
pkg <- readPackageFile
304311
pkgName <- packageNameFromString pkgName'
305312
let pkg' = pkg { depends = filter (/= pkgName) $ depends pkg }
306-
updateAndWritePackageFile pkg'
313+
updateAndWritePackageFile pkg' limitJobs
307314

308-
updateAndWritePackageFile :: PackageConfig -> IO ()
309-
updateAndWritePackageFile pkg = do
310-
installImpl pkg
315+
updateAndWritePackageFile :: PackageConfig -> Maybe Int -> IO ()
316+
updateAndWritePackageFile pkg limitJobs = do
317+
installImpl pkg limitJobs
311318
writePackageFile pkg
312319
echoT "psc-package.json file was updated"
313320

@@ -371,10 +378,10 @@ listSourcePaths = do
371378
-- | Helper for calling through to @purs@
372379
--
373380
-- Extra args will be appended to the options
374-
exec :: [String] -> Bool -> [String] -> IO ()
375-
exec execNames onlyDeps passthroughOptions = do
381+
exec :: [String] -> Bool -> [String] -> Maybe Int -> IO ()
382+
exec execNames onlyDeps passthroughOptions limitJobs = do
376383
pkg <- readPackageFile
377-
installImpl pkg
384+
installImpl pkg limitJobs
378385

379386
paths <- getPaths
380387
let cmdParts = tail execNames
@@ -471,8 +478,8 @@ checkForUpdates applyMinorUpdates applyMajorUpdates = do
471478

472479
data VerifyArgs a = Package a | VerifyAll (Maybe a) deriving (Functor, Foldable, Traversable)
473480

474-
verify :: VerifyArgs Text -> IO ()
475-
verify arg = do
481+
verify :: VerifyArgs Text -> Maybe Int -> IO ()
482+
verify arg limitJobs = do
476483
pkg <- readPackageFile
477484
db <- readPackageSet pkg
478485
case traverse mkPackageName arg of
@@ -505,7 +512,11 @@ verify arg = do
505512
Just pkgInfo -> performInstall (set pkg) pkgName pkgInfo
506513
echoT ("Verifying package " <> runPackageName name)
507514
dependencies <- map fst <$> getTransitiveDeps db [name]
508-
dirs <- mapConcurrently dirFor dependencies
515+
dirs <- case limitJobs of
516+
Nothing -> mapConcurrently dirFor dependencies
517+
Just max' -> do
518+
sem <- newQSem max'
519+
mapConcurrently (bracket_ (waitQSem sem) (signalQSem sem) . dirFor) dependencies
509520
let srcGlobs = map (pathToTextUnsafe . (</> ("src" </> "**" </> "*.purs"))) dirs
510521
procs "purs" ("compile" : srcGlobs) empty
511522

@@ -539,24 +550,27 @@ main = do
539550
[ Opts.command "init"
540551
(Opts.info (initialize <$> optional ((,) <$> (fromString <$> set)
541552
<*> optional (fromString <$> source))
553+
<*> optional limitJobs
542554
Opts.<**> Opts.helper)
543555
(Opts.progDesc "Create a new psc-package.json file"))
544556
, Opts.command "uninstall"
545-
(Opts.info (uninstall <$> pkg Opts.<**> Opts.helper)
557+
(Opts.info (uninstall <$> pkg <*> optional limitJobs Opts.<**> Opts.helper)
546558
(Opts.progDesc "Uninstall the named package"))
547559
, Opts.command "install"
548-
(Opts.info (install <$> optional pkg Opts.<**> Opts.helper)
560+
(Opts.info (install <$> optional pkg <*> optional limitJobs Opts.<**> Opts.helper)
549561
(Opts.progDesc "Install/update the named package and add it to 'depends' if not already listed. If no package is specified, install/update all dependencies."))
550562
, Opts.command "build"
551563
(Opts.info (exec ["purs", "compile"]
552564
<$> onlyDeps "Compile only the package's dependencies"
553565
<*> passthroughArgs "purs compile"
566+
<*> optional limitJobs
554567
Opts.<**> Opts.helper)
555568
(Opts.progDesc "Install dependencies and compile the current package"))
556569
, Opts.command "repl"
557570
(Opts.info (exec ["purs", "repl"]
558571
<$> onlyDeps "Load only the package's dependencies"
559572
<*> passthroughArgs "purs repl"
573+
<*> optional limitJobs
560574
Opts.<**> Opts.helper)
561575
(Opts.progDesc "Open an interactive environment for PureScript"))
562576
, Opts.command "dependencies"
@@ -575,6 +589,7 @@ main = do
575589
(Opts.info (verify <$>
576590
((Package . fromString <$> pkg)
577591
<|> (VerifyAll <$> optional (fromString <$> after)))
592+
<*> optional limitJobs
578593
Opts.<**> Opts.helper)
579594
(Opts.progDesc "Verify that the named package builds correctly. If no package is specified, verify that all packages in the package set build correctly."))
580595
, Opts.command "format"
@@ -586,6 +601,10 @@ main = do
586601
Opts.metavar "PACKAGE"
587602
<> Opts.help "The name of the package to install"
588603

604+
limitJobs = Opts.option Opts.auto $
605+
Opts.long "jobs"
606+
<> Opts.help "Limit the number of jobs that can run concurrently"
607+
589608
source = Opts.strOption $
590609
Opts.long "source"
591610
<> Opts.help "The Git repository for the package set"

0 commit comments

Comments
 (0)