Fork me on GitHub
#cider
<
2022-05-18
>
yuhan08:05:43

I was investigating some performance issues with a long running repl in Cider and found that the buffer local variable nrepl-pending-requests was choked full of tens of thousands of entries - does this happen to anyone else?

jumar08:05:06

Mine is empty

vemv09:05:50

hadn't heard of that! Feel free to sample them (first, last, a few in the middle) and create an issue

practicalli-johnny11:05:36

I assume pending requests backlog would arise if multiple evaluation commands had been issued whilst a long running (perhaps infinitely looping) expression was running. If the REPL buffer is open, there is a spinner displayed in the mode line bar if an evaluation is taking more than a few seconds. The cider-interupt command will stop a long running process, although it may take a few seconds to stop. I am unsure if that interupt will clear pending requests as well.

yuhan14:05:07

I just had a chance to test this again on an empty repo - right after jacking in and evaluating / typing a couple of forms, the nrepl-pending-requests starts growing again, without any signs of clearing old values. In case it wasn't clear, this is a local variable in the cider-repl ... buffer, and there were no pending eval commands.

Value in #<buffer *cider-repl repro/repro:localhost:63257(clj)*>
#s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data
              ("22"
               (closure
                ((status)
                 (response dict "status"
                           ("done" "no-eldoc")
                           "id" "22" "session" "c363b5e7-7ea0-4f2f-9fd6-95a6fe789467")
                 (time0 25222 20710 362122 0)
                 (tooling)
                 (abort-on-input . abort-on-input)
                 (connection . #<buffer *cider-repl repro/repro:localhost:63257(clj)
                             *>)
                 (request "op" "eldoc" "ns"
                          #("repro.core" 0 10
                            (fontified t face clojure-definition-face))
                          "sym" "m")
                 cider-special-mode-truncate-lines cider-print-quota cider-buffer-ns cl-struct-nrepl-response-queue-tags t)
                (resp)
                (nrepl--merge response resp))
               "6" cider--debug-response-handler "10"
               #[257 "\205\301\302!\207"
                     [cljr--debug-mode message "Artifact cache updated"]
                     3 "\n\n(fn _)"]
               "16"
               (closure
                ((causes . t)
                 cider-required-middleware-version t)
                (response)
                (setq causes
                      (cider--handle-stacktrace-response response causes)))
               "26"
               (closure
                ((status)
                 (response dict "id" "26" "session" "c363b5e7-7ea0-4f2f-9fd6-95a6fe789467" "status"
                           ("done" "no-eldoc"))
                 (time0 25222 20710 456284 0)
                 (tooling)
                 (abort-on-input . abort-on-input)
                 (connection . #<buffer *cider-repl repro/repro:localhost:63257(clj)
                             *>)
                 (request "op" "eldoc" "ns"
                          #("repro.core" 0 10
                            (fontified t face clojure-definition-face))
                          "sym" "m")
                 cider-special-mode-truncate-lines cider-print-quota cider-buffer-ns cl-struct-nrepl-response-queue-tags t)
                (resp)
                (nrepl--merge response resp))
               "28"
               (closure
                ((status)
                 (response dict "status"
                           ("done" "no-eldoc")
                           "id" "28" "session" "c363b5e7-7ea0-4f2f-9fd6-95a6fe789467")
                 (time0 25222 20711 478964 0)
                 (tooling)
                 (abort-on-input . abort-on-input)
                 (connection . #<buffer *cider-repl repro/repro:localhost:63257(clj)
                             *>)
                 (request "op" "eldoc" "ns"
                          #("repro.core" 0 10
                            (fontified t face clojure-definition-face))
                          "sym" "ma")
                 cider-special-mode-truncate-lines cider-print-quota cider-buffer-ns cl-struct-nrepl-response-queue-tags t)
                (resp)
                (nrepl--merge response resp))
               "29"
               (closure
                ((status "done")
                 (response dict "status"
                           ("done")
                           "added" "1.0" "arglists-str" "[form]" "column" 1 "doc" "If form represents a macro form, returns its expansion,\n  else returns form." "file" "jar:file:/Users/yuhan/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/core.clj" "id" "29" "line" 4018 "name" "macroexpand-1" "ns" "clojure.core" "resource" "clojure/core.clj" "see-also"
                           ("clojure.core/macroexpand" "clojure.walk/macroexpand-all")
                           "session" "c363b5e7-7ea0-4f2f-9fd6-95a6fe789467" "static" "true")
                 (time0 25222 20711 482763 0)
                 (tooling)
                 (abort-on-input)
                 (connection . #<buffer *cider-repl repro/repro:localhost:63257(clj)
                             *>)
                 (request "op" "info" "ns"
                          #("repro.core" 0 10
                            (fontified t face clojure-definition-face))
                          "sym"
                          #("macroexpand-1" 0 1
                            (ns "clojure.core" type "function" face
                                (completions-common-part))
                            1 2
                            (face
                             (completions-common-part))
                            2 3
                            (face
                             (completions-first-difference))))
                 cider-special-mode-truncate-lines cider-print-quota cider-buffer-ns cl-struct-nrepl-response-queue-tags t)
                (resp)
                (nrepl--merge response resp))
               "30"
               (closure
                ((status)
                 (response dict "id" "30" "session" "c363b5e7-7ea0-4f2f-9fd6-95a6fe789467" "status"
                           ("done" "no-eldoc"))
                 (time0 25222 20711 517791 0)
                 (tooling)
                 (abort-on-input . abort-on-input)
                 (connection . #<buffer *cider-repl repro/repro:localhost:63257(clj)
                             *>)
                 (request "op" "eldoc" "ns"
                          #("repro.core" 0 10
                            (fontified t face clojure-definition-face))
                          "sym" "ma")
                 cider-special-mode-truncate-lines cider-print-quota cider-buffer-ns cl-struct-nrepl-response-queue-tags t)
                (resp)
                (nrepl--merge response resp))))

yuhan14:05:09

In particular, it seems that every exception thrown will add another entry to this hash table in the form of :

("17"
               (closure
                ((causes . t)
                 cider-required-middleware-version t)
                (response)
                (setq causes
                      (cider--handle-stacktrace-response response causes)))
               "6" cider--debug-response-handler "10"
               #[257 "\205\301\302!\207"
                     [cljr--debug-mode message "Artifact cache updated"]
                     3 "\n\n(fn _)"]

robert-stuttaford14:05:38

i am up to no good with looping and testing Datomic transactions with datomic.api/with . i'm getting a StackOverflowException, which serves me right. however, i'm only seeing the first 1000 or so frames of this exception in *cider-error* , which is hiding the genesis of the stacktrace. is there a way to see the full stacktrace, no matter how long it may take my undeserving computer to produce for me?

vemv14:05:50

perhaps you can just operate on *e on the repl?

gratitude-thank-you 1
robert-stuttaford15:05:32

gosh. guess who's never used *e before -blush-

clojure-spin 1
robert-stuttaford05:05:57

yeah so the exception is occurring inside a ring handler, so i don't have *e available to me for it

robert-stuttaford05:05:03

guess i need to repro via the repl!

robert-stuttaford05:05:40

ok so *e also only has 1000 frames

vemv07:05:50

do you think it's a display limitation or a jvm limitation in play? For the latter there's "-XX:MaxJavaStackTraceDepth=1000000"

lilactown20:05:14

I'm in a clojure (deps.edn) project that includes shadow-cljs as a dependency and does some custom setup with it. I jack in using the clojure-cli option and and start a watch from the REPL. I'd like to drop down into that CLJS REPL after the watch is done building, but when I try and run (shadow.cljs.devtools.api/repl :app) it instead gives me an Stdin: prompt that I have to type directly into, rather than changing the buffer into a cljs REPL and allowing me to evaluate forms in CLJ(S|C) files

thheller05:05:30

if the nrepl middleware is not loaded repl defaults to using a regular REPL loop reading from stdin. I'm guessing you don't have the middleware loaded https://shadow-cljs.github.io/docs/UsersGuide.html#_embedded_nrepl_server

lilactown14:05:07

hmm I can't tell yet if that fixed it