Skip to content

Commit 2e43d87

Browse files
committed
first pass at experimental support for parallel builds
1 parent 3e1af21 commit 2e43d87

File tree

1 file changed

+61
-12
lines changed

1 file changed

+61
-12
lines changed

src/main/clojure/cljs/closure.clj

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
[java.net URL]
4848
[java.util.logging Level]
4949
[java.util List Random]
50-
[java.util.concurrent TimeUnit]
50+
[java.util.concurrent TimeUnit LinkedBlockingDeque]
5151
[com.google.javascript.jscomp CompilerOptions CompilationLevel
5252
CompilerOptions$LanguageMode SourceMap$Format
5353
SourceMap$DetailLevel ClosureCodingConvention SourceFile
@@ -741,21 +741,70 @@
741741
(ana/warning :unprovided @env/*compiler* {:unprovided (sort unprovided)}))
742742
inputs))
743743

744+
(defn compile-task [^LinkedBlockingDeque deque input-set compiled opts]
745+
(loop [ns-info (.pollFirst deque)]
746+
(when ns-info
747+
(let [{:keys [requires]} ns-info
748+
input-set' @input-set]
749+
(if (every? #(not (contains? input-set' %)) requires)
750+
(do
751+
(try
752+
(swap! compiled conj
753+
(-compile (or (:source-file ns-info)
754+
(:source-forms ns-info))
755+
; - ns-info -> ns -> cljs file relpath -> js relpath
756+
(merge opts
757+
{:output-file (comp/rename-to-js
758+
(util/ns->relpath (:ns ns-info)))})))
759+
(catch Throwable e
760+
(util/debug-prn e)))
761+
(when-let [ns (:ns ns-info)]
762+
(swap! input-set disj ns))
763+
(recur (.pollFirst deque)))
764+
(do
765+
(Thread/sleep 10)
766+
(recur ns-info)))))))
767+
768+
(defn parallel-compile-sources [inputs compiler-stats opts]
769+
(let [deque (LinkedBlockingDeque. (count inputs))
770+
input-set (atom #{})
771+
cnt (+ 2 (.. Runtime getRuntime availableProcessors))
772+
agents (repeatedly cnt
773+
#(agent nil
774+
:error-handler
775+
(fn [err]
776+
(util/debug-prn err))))
777+
compiled (atom [])]
778+
(doseq [ns-info (reverse inputs)]
779+
(when-let [ns (:ns ns-info)]
780+
(swap! input-set conj ns))
781+
(.push deque ns-info))
782+
(doseq [agent agents]
783+
(send agent
784+
(fn [agent]
785+
(compile-task deque input-set compiled opts)
786+
agent)))
787+
(util/measure compiler-stats
788+
"Compile sources" (apply await agents))
789+
@compiled))
790+
744791
(defn compile-sources
745792
"Takes dependency ordered list of IJavaScript compatible maps from parse-ns
746793
and compiles them."
747794
[inputs compiler-stats opts]
748-
(util/measure compiler-stats
749-
"Compile sources"
750-
(binding [comp/*inputs* (zipmap (map :ns inputs) inputs)]
751-
(doall
752-
(for [ns-info inputs]
753-
; TODO: compile-file calls parse-ns unnecessarily to get ns-info
754-
; TODO: we could mark dependent namespaces for recompile here
755-
(-compile (or (:source-file ns-info)
756-
(:source-forms ns-info))
757-
; - ns-info -> ns -> cljs file relpath -> js relpath
758-
(merge opts {:output-file (comp/rename-to-js (util/ns->relpath (:ns ns-info)))})))))))
795+
(if (:parallel-build opts)
796+
(parallel-compile-sources inputs compiler-stats opts)
797+
(util/measure compiler-stats
798+
"Compile sources"
799+
(binding [comp/*inputs* (zipmap (map :ns inputs) inputs)]
800+
(doall
801+
(for [ns-info inputs]
802+
; TODO: compile-file calls parse-ns unnecessarily to get ns-info
803+
; TODO: we could mark dependent namespaces for recompile here
804+
(-compile (or (:source-file ns-info)
805+
(:source-forms ns-info))
806+
; - ns-info -> ns -> cljs file relpath -> js relpath
807+
(merge opts {:output-file (comp/rename-to-js (util/ns->relpath (:ns ns-info)))}))))))))
759808

760809
(defn add-goog-base
761810
[inputs]

0 commit comments

Comments
 (0)