This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-05-24
Channels
- # aleph (1)
- # beginners (43)
- # calva (22)
- # cider (51)
- # clerk (1)
- # clj-kondo (20)
- # clojure (29)
- # clojure-denmark (1)
- # clojure-europe (73)
- # clojure-finland (28)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-spec (7)
- # clojure-uk (4)
- # clojurescript (12)
- # data-science (2)
- # datomic (51)
- # events (1)
- # fulcro (20)
- # hyperfiddle (28)
- # integrant (6)
- # malli (20)
- # matrix (2)
- # music (1)
- # off-topic (66)
- # reitit (17)
- # releases (5)
- # ring (1)
- # shadow-cljs (31)
- # xtdb (6)
has anything changed recently in the cider-interrupt
function? It used to be pretty effective at stopping stuff in the REPL and now it seems that pressing it makes the prompt appear but doesn’t stop whatever is running
not that I heard of
are you familiar with the fact that it first tries to interrupt gracefully (via Thread/interrupt
), and then only uses Thread .stop
as a last resource.
You may need to try twice to force the stop
ping.
thanks for the tip
This seems to be persisting, I have this function:
(defn infinite []
(while true
(apply * (range 100))))
I run it in the REPL, I see the CPU of the java process going to 100%, I then press C-c C-c
, I get back a responsive REPL but CPU stays at 100%.REPL sample session:
;; Connected to nREPL server -
;; CIDER 1.7.0 (Côte d'Azur), nREPL 1.0.0
;; Clojure 1.12.0-alpha2, Java 20.0.1
;; Docs: (doc function-name)
;; (find-doc part-of-name)
;; Source: (source function-name)
;; Javadoc: (javadoc java-object-or-class)
;; Exit: <C-c C-q>
;; Results: Stored in vars *1, *2, *3, an exception in *e;
;; Startup: /usr/local/bin/clojure -A:dev -Sdeps '{:deps {nrepl/nrepl {:mvn/version "1.0.0"} cider/cider-nrepl {:mvn/version "0.30.0"}} :aliases {:cider/nrepl {:main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"]}}}' -M:cider/nrepl
user>
zuper.nlp> (infinite)
ERROR:
zuper.nlp> (+ 1 1)
2
the ERROR:
line appears some time after I press C-c C-c
a subsequent call to (infinite)
makes java got to 200%, and it stays there even after being interrupted
this is on macOS Monterey (12.3.1)
Does the error occur if you manually call M-x cider-interrupt
? I ask because C-c C-c
isn't bound to cider interrupt for me, but I'm not totally sure if that's because my setup has been customized.
I can try, but:
C-c C-c runs the command cider-interrupt (found in cider-repl-mode-map), which
is an interactive byte-compiled Lisp function in 'cider-client.el'.
It is bound to C-c C-c, C-c C-b, <menu-bar> <repl> <Interrupt evaluation>,
<menu-bar> <repl> <Test> <Interrupt running tests>.
(cider-interrupt)
Interrupt any pending evaluations.
Oh, nevermind. C-c C-c
is cider interrupt in the repl for me, but not in the clj file.
Does the problem also happen if you don't load any code and just try it from the user
namespace?
let me see…
yes, it still happens in a fresh REPL:
user> (while true
(apply * (range 100)))
ERROR:
user>
and you have confirmed the issue happens in a "clean" project without any plugins or dependencies?
Basically, just trying to narrow it down to make sure the problem is cider related rather than some other dependency
sure, let me give that a try
OK, so I’ve renamed my ~/.clojure
to something else (because I had a deps.edn in there) and made a new project that has just a deps.edn file in the folder with:
{:deps {org.clojure/clojure {:mvn/version "1.12.0-alpha2"}}}
And I’m still getting the same behaviouroh, interesting. I'm seeing it now
I can start changing the versions of Clojure, CIDER, the JDK etc to see which one is to blame
oh can you actually reproduce it?
I’m so glad!
I think I was seeing it before, but just didn't check the CPU usage.
it’s my fans that gave it away, it’s pretty hot over here
My macbook air quietly churns.
would you like me to write this up as an issue on github?
I don't work on cider. I was just trying to help debug.
oh, many thanks in any case, I’ll report this and send you the link in case you’d like to mention that you’re also experiencing it
maybe mentioning your versions would be helpful
I wanted to check if writing some code to the interruption also had the same problem:
(defn start-thread-and-kill []
(let [t1 (Thread.
(fn []
(infinite)))
t2 (Thread.
(fn []
(Thread/sleep 3000)
(.stop t1)))]
(.start t1)
(.start t2)
(.join t1)))
and it does.
Which led me to check Thread.stop for https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/Thread.html#stop(). Compared to https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/Thread.html#stop(), it now says:
> Throws:
> UnsupportedOperationException
- always
Interestingly, cider-interrupt works for this:
user> (defn infinite []
(while true
(prn :foo)
(Thread/sleep 1000)))
#'user/infinite
user> (infinite)
:foo
:foo
Execution error (InterruptedException) at java.lang.Thread/sleep0 (Thread.java:-2).
sleep interrupted
user>
if you call thread.stop()
in Java 20, it looks like it doesn't stop the thread instead just throws UnsupportedOperationException.
but this keeps printing!
(defn infinite []
(while true
(prn :foo)))
As mentioned earlier, cider-interrupt
first calls thread.interrupt()
and then waits a bit before calling thread.stop()
, so since sleep checks the interrupt flag, then it works.
If you remove the sleep, then there's no longer any code that checks the interrupt flag
yeah, that makes sense
This also gracefully stops:
(defn infinite-with-interrupt []
(while (not (Thread/interrupted))
(apply * (range 100))))
So it seems like the root "cause" is that thread.stop()
no longer actually stops the thread starting in Java 20.
Downgrading to openjdk 17 fixes this
👍 , yes, that's good to double check.
Not just that, but also essential for me to have a working REPL while the good developers of CIDER work on a more permanent fix, thank you very much for your help with this!
Just skimmed through the ticket and basically, it doesn't seem like there's any way to force another thread to stop if the thread itself doesn't cooperatively check if it should stop itself.
Maybe some answer will present itself via project loom?
My notes on the topic https://github.com/clojure-emacs/cider/issues/3351#issuecomment-1587036038
This seems to be persisting, I have this function:
(defn infinite []
(while true
(apply * (range 100))))
I run it in the REPL, I see the CPU of the java process going to 100%, I then press C-c C-c
, I get back a responsive REPL but CPU stays at 100%.