cider-nrepl
cider-nrepl copied to clipboard
Problem with breakpoints on multiple threads
Expected behavior
Breakpoints run on multiple threads simultaneously. If multiple breakpoints are running at the same time, a mechanism exists to switch between them.
Actual behavior
I can't find a mechanism for switching between simultaneous breakpoints. If two breakpoints are running simultaneously, one of them appears to hang:
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc))
(def results
[(future (inc-counter))
(future (inc-counter))])
;; If inc-counter is not instrumented:
;; @counter:
;; 2
;; results:
;; [#<Future@7c262db8: 1> #<Future@33382bde: 2>]
;; If inc-counter is instrumented and the breakpoint prompt is exited by pressing `c`:
;; @counter:
;; 1
;; results:
;; [#<Future@5b3f971d: :pending> #<Future@51a1bc5d: 1>]
Steps to reproduce the problem
See example above
Environment & Version information
cider-nrepl version
Not clear how to check this (installed automatically with cider-jack-in), but the cider emacs package information version is 20190720.1656.
Java version
1.8.0_221
Operating system
Windows 10
@Malabarba Any thoughts on this one?
I think this is a duplicate of another issue we have here, at least I kinda remember answering something like this recently. :-)
cider-nrepl does support multiple threads (each thread that hits a breakpoint waits for input independently). The problem is that the cider.el frontend doesn't know how to handle that (when it gets the second input request it forgets the first one).
IIRC, on some other issue I suggested we make cider-nrepl skip breakpoints when it knows there's another breakpoint already waiting for input. That is technically a regression in terms of features, but that's only a problem if there's another client other than Emacs using the debugger (and if that client supports parallel breakpoints), which I don't think is the case.
Thanks for your response @Malabarba , I'm having some trouble finding that issue (maybe related to #460?), here or on the cider repo, but yeah it sounds like it's the same thing. I take it frontend support for parallel breakpoints is infeasible?
It's certainly feasilble. But someone would have to do it. :-) Right now, when cider.el receives an input request it jumps to the breakpoint location and turns on debug-mode. One way to implement handling multiple requests would be to keep track of a queue of them, and after resolving one go to the other.
The problem with that is that it might be confusing for the user. For example, they enter a breakpoint, then hit n
thinking it will move to the next expression, but instead it just opens the same place again because another thread is executing the same function.