Skip to content

Commit

Permalink
remove hawk library used for file watching
Browse files Browse the repository at this point in the history
Only used to be used on macOS since it was slightly faster
than the default JVM implementation. However in Big Sur it seems
to cause issues and break completely or just be a lot slower.

Win/Linux are unaffected since they always used the default JVM
implemenation. Big Sur seems to be faster. Previous macOS version
might get a tad slower but I haven't tested that in a long time
and it used to be no more than 2secs which is fine. Better than
relying on an unmaintained possibly broken library.

fixes #837
fixes #774
  • Loading branch information
thheller committed Feb 3, 2021
1 parent cabc30d commit f3b89b5
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 227 deletions.
2 changes: 0 additions & 2 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@
;; for pathom
[org.clojure/test.check "1.1.0"]

;; experimental
[hawk "0.2.11"]
[thheller/shadow-cljsjs "0.0.21"]]

:source-paths
Expand Down
103 changes: 78 additions & 25 deletions src/main/shadow/cljs/devtools/server/fs_watch.clj
Original file line number Diff line number Diff line change
@@ -1,31 +1,84 @@
(ns shadow.cljs.devtools.server.fs-watch
(:require [shadow.jvm-log :as log]
[clojure.string :as str]))
(:require [shadow.build.api :as cljs]
[clojure.core.async :as async :refer (alt!! thread >!!)]
[shadow.cljs.devtools.server.util :as util]
[shadow.cljs.devtools.server.system-bus :as system-bus]
[clojure.java.io :as io]
[clojure.string :as str]
[shadow.build.resource :as rc])
(:import (shadow.util FileWatcher)
(java.io File)))

(defn service? [x]
(and (map? x)
(::service x)))

;; hawk already uses the jvm watcher on win/linux
;; not much benefit doing this again
(defn poll-changes [{:keys [dir ^FileWatcher watcher]}]
(let [changes (.pollForChanges watcher)]
(when (seq changes)
(->> changes
(map (fn [[name event]]
{:dir dir
:name (rc/normalize-name name)
:ext (when-let [x (str/last-index-of name ".")]
(subs name (inc x)))
:file (io/file dir name)
:event event}))
;; ignore empty files
(remove (fn [{:keys [event ^File file] :as x}]
(and (not= event :del)
(zero? (.length file)))))
))))

(def os-name (System/getProperty "os.name"))
(defn watch-loop
[watch-dirs control publish-fn]

(loop []
(alt!!
control
([_]
:terminated)

(async/timeout 500)
([_]
(let [fs-updates
(->> watch-dirs
(mapcat poll-changes)
(into []))]

(when (seq fs-updates)
(publish-fn fs-updates))

(recur)))))

;; shut down watchers when loop ends
(doseq [{:keys [^FileWatcher watcher]} watch-dirs]
(.close watcher))

::shutdown-complete)

(defn start [config directories file-exts publish-fn]
(let [ns-sym
(if (and (str/includes? os-name "Mac") (not (false? (:hawk config))))
;; macOS doesn't have native support so it uses polling
;; which means 2sec delay, hawk does the native stuff
;; so its a lot faster but doesn't properly support delete
'shadow.cljs.devtools.server.fs-watch-hawk
;; jvm on windows/linux supports watch fine
'shadow.cljs.devtools.server.fs-watch-jvm)]

(log/debug ::fs-watch {:ns ns-sym})

(require ns-sym)

(let [start-var (ns-resolve ns-sym 'start)]
(-> (start-var config directories file-exts publish-fn)
(assoc ::ns ns-sym)))))

(defn stop [{::keys [ns] :as svc}]
(let [stop-var (ns-resolve ns 'stop)]
(stop-var svc)))
{:pre [(every? #(instance? File %) directories)
(coll? file-exts)
(every? string? file-exts)]}
(let [control
(async/chan)

watch-dirs
(->> directories
(map (fn [^File dir]
{:dir dir
:watcher (FileWatcher/create dir (vec file-exts))}))
(into []))]

{::service true
:control control
:watch-dirs watch-dirs
:thread (thread (watch-loop watch-dirs control publish-fn))}))

(defn stop [{:keys [control thread] :as svc}]
{:pre [(service? svc)]}
(async/close! control)
(async/<!! thread))


114 changes: 0 additions & 114 deletions src/main/shadow/cljs/devtools/server/fs_watch_hawk.clj

This file was deleted.

84 changes: 0 additions & 84 deletions src/main/shadow/cljs/devtools/server/fs_watch_jvm.clj

This file was deleted.

3 changes: 1 addition & 2 deletions src/repl/shadow/cljs/watch_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
(:require
[clojure.test :refer (is deftest)]
[clojure.java.io :as io]
[shadow.cljs.devtools.server.fs-watch-jvm :as fs-jvm]
[shadow.cljs.devtools.server.fs-watch-hawk :as fs-hawk]))
[shadow.cljs.devtools.server.fs-watch :as fs]))


(comment
Expand Down

0 comments on commit f3b89b5

Please sign in to comment.