This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-04-24
Channels
- # announcements (8)
- # babashka (16)
- # beginners (18)
- # biff (4)
- # calva (18)
- # clj-kondo (20)
- # clojure (24)
- # clojure-brasil (1)
- # clojure-europe (13)
- # clojure-nl (1)
- # clojure-norway (35)
- # clojure-uk (3)
- # clojurescript (16)
- # core-async (50)
- # cursive (5)
- # data-science (5)
- # datalevin (5)
- # datomic (69)
- # dev-tooling (18)
- # fulcro (3)
- # gratitude (1)
- # honeysql (5)
- # hyperfiddle (4)
- # jackdaw (2)
- # jobs-discuss (24)
- # lambdaisland (7)
- # lsp (16)
- # malli (5)
- # off-topic (65)
- # overtone (16)
- # pathom (28)
- # portal (3)
- # re-frame (24)
- # releases (1)
- # shadow-cljs (101)
Hello! Do any one know how to stop task execution in promesa?
(def task
(p/vthread
(loop []
(println "x…")
(p/sleep 500)
(recur))))
p/vthread returns CompletableFutureI don't think there is a way of interrupting a loop inside a CompletableFuture without explicitly checking a flag before doing the (recur). Checking (Thread/interrupted) doesn't work either because the cancel don't interrupt the future thread.
You can do it with normal Clojure futures like this :
clj
Clojure 1.11.1
user=> (def f (future (loop [] (println "x") (Thread/sleep 1000) (when-not (Thread/interrupted) (recur)))))
x
x
x
(future-cancel f)
true
user=>
I wrote this for this problem: https://github.com/k13labs/futurama
You can use a Fiber pool with it and it effectively works the same, ofc with core async semantics instead of promesa so use at your own risk
@U0739PUFQ Thanks! but for clojure.core/future as i can see there is no need to check (Thread/interrupted) (future-cancel task) interrupt task execution
@U07MK6PLN Thank you! cool lib, but it look like a bit overhead for my task
@U04410FUMCL you do need the (Thread/interrupted) check if you don't have the Thread/sleep. Something like this will not cancel :
user=> (def a (atom 0))
#'user/a
user=> (def f (future (loop [] (swap! a inc) (recur))))
#'user/f
user=> @a
69724592
user=> (future-cancel f)
true
user=> @a
620767611
user=> @a
653178836
user=> @a
679249561
There is no way to stop a loop non cooperatively in the JVM since the https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html@U0739PUFQ thank you, thats interesting!
@U04410FUMCL the problem I faced with this, is that if you cancel a CompletableFuture, it does not interrupt the underlying Thread upon which the Future that will eventually complete the completable future is running. So if your code returns a completable future, it needs to be wired up to perform that cancelation if the CompletableFuture fails (by cancellation or some other means)
there are other edge cases as well when you have nested calls to completable futures, but at a simplest level if you just need to cancel the task you started, your code needs to be cooperative and the library code that returns the completable future needs to do something like this: https://github.com/k13labs/futurama/blob/main/src/futurama/core.clj#L189
@U0739PUFQ @U07MK6PLN i think i will go with this
(def task
(let [t (p/deffered)]
(p/vthread
#(while (p/pendding? t)
(println "x…")
(p/sleep 500)))
t))
(p/cancel! task)
Is there a neat way to list all functions from the babashka.fs
namespace that I’m using in my Clojure project?
(I suppose i could try to grep for fs/
or something similar, but that would give flaky results, and I wonder if this problem perhaps has been solved before)
$ clj-kondo --lint src --config '{:analysis true :output {:format :edn}}' | bb -e '(def ana (edn/read-string (slurp *in*))) (prn (->> ana :analysis :var-usages (filter #(= (:to %) (symbol "babashka.fs")))))' | jet
This is amazing. Thank you! 💯 🙏 I was able to make your very long line even longer:
$ clj-kondo --lint src --config '{:analysis true :output {:format :edn}}' | bb -e '(def ana (edn/read-string (slurp *in*))) (prn (->> ana :analysis :var-usages (filter #(= (:to %) (symbol "babashka.fs"))) (map :name) (into #{}) sort))' | jet
(canonicalize
create-dirs
delete-if-exists
directory?
exists?
file
file-name
file-time->millis
glob
last-modified-time
list-dir
which
xdg-config-home)
frequencies (sort-by second) reverse
could also be interesting, the most used ones:
I'm getting:
([exists? 22]
[file 11]
[file-separator 10]
[parent 8]
[path 8]
[create-dirs 6]
[extension 5]
[read-all-bytes 5]
[directory? 3]
[unixify 3]
[delete-tree 3]
[cwd 3]
[strip-ext 2]
[glob 2]
[canonicalize 2]
[relativize 2]
[components 1]
[absolutize 1]
[delete-if-exists 1]
[normalize 1]
[absolute? 1]
[windows? 1])
Yes, count is nice! Here’s mine (edited to include cli and process):
$ clj-kondo --lint src --config '{:analysis true :output {:format :edn}}' | bb -e '(def ana (edn/read-string (slurp *in*))) (prn (->> ana :analysis :var-usages (filter #('"'"'#{babashka.fs babashka.process babashka.cli} (:to %))) (map (juxt :to :name)) frequencies (sort-by second) reverse))' | jet
([[babashka.fs file] 7]
[[babashka.fs exists?] 6]
[[babashka.fs file-name] 3]
[[babashka.fs canonicalize] 3]
[[babashka.fs last-modified-time] 3]
[[babashka.fs list-dir] 3]
[[babashka.process shell] 3]
[[babashka.fs create-dirs] 2]
[[babashka.cli coerce] 2]
[[babashka.fs xdg-config-home] 2]
[[babashka.fs which] 2]
[[babashka.process process] 1]
[[babashka.fs delete-if-exists] 1]
[[babashka.cli dispatch] 1]
[[babashka.process tokenize] 1]
[[babashka.fs directory?] 1]
[[babashka.fs file-time->millis] 1]
[[babashka.fs glob] 1])