Closed rgkirch closed 1 year ago
I'm on windows 10. bb version v0.7.4-snapshot
hey, is it the same event you're seeing twice? or is one of them chmod and the other edit?
(def w1 (fw/watch "file.clj"
(fn [{:keys [type path] :as _event}]
(let [now (System/currentTimeMillis)]
(prn [:type type :path path :now now])))
{:recursive true
:delay-ms 250}))
[:type :write :path "file.clj" :now 1649072989448]
[:type :write :path "file.clj" :now 1649072989448]
(def count (atom 0))
(def w1 (fw/watch "file.clj"
(fn [{:keys [type path] :as _event}]
(let [now (System/currentTimeMillis)]
(swap! count inc)
(prn [:type type :path path :now now :count @count])))
{:recursive true
:delay-ms 250}))
saving file prints
[:type :write :path "file.clj" :now 1649073215153 :count 1]
[:type :write :path "file.clj" :now 1649073215156 :count 2]
editing and saving again prints
[:type :write :path "file.clj" :now 1649073268285 :count 3]
[:type :write :path "file.clj" :now 1649073268285 :count 4]
I'm connecting to bb --nrepl-server
from emacs over cider.
Could be something specific to the windows apis or the way the editor saves it. I get two events on my linux machine when saving with vim: chmod and write. Could you try something like echo "foo" > the-file
and see if you still have the duplicate events? @borkdude can you try in windows? I dont have a windows machine off hand.
Will do later this week. Perhaps looking at the issues of the go lib and/or upgrading it will also help.
https://github.com/fsnotify/fsnotify/issues/206 I did try deduping but it introduced other strange behavior.
(defn on-change
([f paths]
(on-change f paths {}))
([f paths {:keys [timeout]
:or {timeout 1000}}]
(let [cache (atom {})
watchers (for [path paths]
(fw/watch path
(fn [{:keys [type path] :as _event}]
(let [now (System/currentTimeMillis)]
(when (= type :write)
(when (or (not (contains? @cache path))
(< timeout (- now (@cache path))))
(swap! cache assoc path now)
(f path)))))
{:recursive true
:delay-ms 250}))]
(fn unwatch-all [] (doseq [w watchers]
(fw/unwatch w))))))
I'm not a fan of trying to "hide" a bug of the underlying library. The best you can do if the underlying library is compensate for this in your own app.
There is another filewatcher pod which is built in Rust, which you could try too:
https://github.com/babashka/pod-registry/blob/master/examples/filewatcher.clj
I guess we don't have a windows build for it yet?
🤦 Maybe switch to Github actions for that one then so we can more easily make a matrix
There is another filewatcher pod which is built in Rust, which you could try too:
It doesn't support Windows.
(fw/watch "folder/"
(fn [event] (prn event))
{:recursive true
:delay-ms 2000})
Saving the file with emacs generates 4 messages but echo "text" >> folder/file.txt
generates 2 messages.
{:type :write, :path "folder\\file.txt"}
{:type :write, :path "folder\\file.txt"}
{:type :write, :path "folder\\file.txt"}
{:type :write, :path "folder\\file.txt"}
{:type :write, :path "folder\\file.txt"}
I encountered this problem as well on Windows 10, I tried saving in VSCode and Notepad and both fires the write events twice
but then I did some digging and found a suggestion from user steve-kessel-aero and a Go code from sejongk in this thread: https://github.com/fsnotify/fsnotify/issues/122 which suggest making a loop that will fire the latest recorded events on a specific time interval
then I tried writing that Go code in Clojure and come up with this code below:
(require '[babashka.pods :as pods])
(pods/load-pod 'org.babashka/fswatcher "0.0.3")
(require '[pod.babashka.fswatcher :as fw])
(require '[clojure.core.async :refer [go-loop timeout <!]])
(def target "src")
(println "watching" target)
(def latest-event (atom nil))
(fw/watch target (fn [event] (reset! latest-event event))
{:recursive true})
(defn handle [event]
(println "handled this:" event))
(go-loop [time-unit 1]
(<! (timeout 100))
(let [[event _] (reset-vals! latest-event nil)]
(some-> event handle))
(recur (inc time-unit)))
@(promise)
which served for my use case quite well, so I hope this can help (also I still have little experience with Clojure so any feedback will be greatly appreciated)
@keychera looks good to me!
I think this is now fixed by #19
When I modify the file then it prints twice and increments count from 0 to 2.