Skip to content

Commit

Permalink
FEATURE: configurable wait time for file changes (bhauman#625)
Browse files Browse the repository at this point in the history
Looks good!
  • Loading branch information
featheredtoast authored and Bruce Hauman committed Dec 2, 2017
1 parent a759228 commit 0f62d6d
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 47 deletions.
7 changes: 7 additions & 0 deletions sidecar/resources/conf-fig-docs/FigwheelOptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,10 @@ to prevent ANSI color codes in figwheel output set :ansi-color-output
to false. Default: true

:ansi-color-output false

:wait-time-ms

The number of milliseconds to wait before issuing reloads. Set this higher
to wait longer for changes. Default: 50

:wait-time-ms 50
3 changes: 2 additions & 1 deletion sidecar/src/figwheel_sidecar/components/cljs_autobuild.clj
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@
(watching/watch!
(:hawk-options figwheel-server)
(source-paths-that-affect-build build-config)
(partial execute-build this)))))
(partial execute-build this)
(:wait-time-ms figwheel-server)))))
this))
(stop [this]
(when (:file-watcher this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
(fn []
(utils/bind-logging
log-writer
(notification-handler this files))))))))
(notification-handler this files)))))
(:wait-time-ms figwheel-server-options))))
(do
(println "Figwheel: No watch paths configured for" watcher-name)
this)))
Expand Down
11 changes: 10 additions & 1 deletion sidecar/src/figwheel_sidecar/schemas/config.clj
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@
::builds
::reload-clj-files
::hawk-options
::cljs-build-fn])
::cljs-build-fn
::wait-time-ms])

"A Map of options that determine the behavior of the Figwheel system.
:figwheel {
Expand Down Expand Up @@ -310,6 +312,13 @@ be useful for certain docker environments.
:hawk-options {:watcher :polling}" )

(def-key ::wait-time-ms integer?

"The number of milliseconds to wait before issuing reloads. Set this higher
to wait longer for changes. Default: 50
:wait-time-ms 50")

(def-key ::reload-clj-files
(s/or
:bool boolean?
Expand Down
92 changes: 48 additions & 44 deletions sidecar/src/figwheel_sidecar/watching.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
;;; we are going to have to throttle this
;; so that we can catch more than one file at a time

(defn take-until-timeout [in]
(let [time-out (timeout 50)]
(defn take-until-timeout [in t]
(let [time-out (timeout t)]
(go-loop [collect []]
(when-let [[v ch] (alts! [in time-out])]
(if (= ch time-out)
Expand All @@ -38,53 +38,57 @@
(merge {:sensitivity :high} hawk-options)
hawk-options)))

(defn watch! [hawk-options source-paths callback]
(let [hawk-options (default-hawk-options hawk-options)
throttle-chan (chan)
(defn watch!
([hawk-options source-paths callback wait-time-ms]
(let [hawk-options (default-hawk-options hawk-options)
wait-time-ms (or wait-time-ms 50)
throttle-chan (chan)

{:keys [files dirs]} (files-and-dirs source-paths)
individual-file-map (single-files files)
canonical-source-dirs (set (map #(.getCanonicalPath %) dirs))
{:keys [files dirs]} (files-and-dirs source-paths)
individual-file-map (single-files files)
canonical-source-dirs (set (map #(.getCanonicalPath %) dirs))

source-paths (distinct
(concat (map str dirs)
(map #(.getParent %) files)))
source-paths (distinct
(concat (map str dirs)
(map #(.getParent %) files)))

valid-file? (fn [file]
(and file
(.isFile file)
(not (.isHidden file))
(let [file-path (.getCanonicalPath file)
n (.getName file)]
(and
(not= \. (first n))
(not= \# (first n))
(or
;; just skip this if
;; there are no individual-files
(empty? individual-file-map)
;; if file is on a path that is already being watched we are cool
(some #(is-subdirectory % file-path) canonical-source-dirs)
;; if not we need to see if its an individually watched file
(when-let [acceptable-paths
(get individual-file-map
(.getCanonicalPath (.getParentFile file)))]
(some #(= (.getCanonicalPath %) file-path) acceptable-paths)))))))
watcher (hawk/watch! hawk-options
[{:paths source-paths
:filter hawk/file?
:handler (fn [ctx e]
(put! throttle-chan e))}])]
valid-file? (fn [file]
(and file
(.isFile file)
(not (.isHidden file))
(let [file-path (.getCanonicalPath file)
n (.getName file)]
(and
(not= \. (first n))
(not= \# (first n))
(or
;; just skip this if
;; there are no individual-files
(empty? individual-file-map)
;; if file is on a path that is already being watched we are cool
(some #(is-subdirectory % file-path) canonical-source-dirs)
;; if not we need to see if its an individually watched file
(when-let [acceptable-paths
(get individual-file-map
(.getCanonicalPath (.getParentFile file)))]
(some #(= (.getCanonicalPath %) file-path) acceptable-paths)))))))
watcher (hawk/watch! hawk-options
[{:paths source-paths
:filter hawk/file?
:handler (fn [ctx e]
(put! throttle-chan e))}])]

(go-loop []
(when-let [v (<! throttle-chan)]
(let [files (<! (take-until-timeout throttle-chan))]
(when-let [result-files (not-empty (distinct (filter valid-file? (map :file (cons v files)))))]
(callback result-files)))
(recur)))
(go-loop []
(when-let [v (<! throttle-chan)]
(let [files (<! (take-until-timeout throttle-chan wait-time-ms))]
(when-let [result-files (not-empty (distinct (filter valid-file? (map :file (cons v files)))))]
(callback result-files)))
(recur)))

{:watcher watcher
:throttle-chan throttle-chan}))
{:watcher watcher
:throttle-chan throttle-chan}))
([hawk-options source-paths callback]
(watch! hawk-options source-paths callback 50)))

(defn stop! [{:keys [throttle-chan watcher]}]
(hawk/stop! watcher)
Expand Down

0 comments on commit 0f62d6d

Please sign in to comment.