-
Notifications
You must be signed in to change notification settings - Fork 180
Description
I was debugging a problem as shadow-cljs user reported, and while trying to debug that I noticed that the shadow-cljs UI inspect wasn't working or very sluggish, frequently running into OutOfMemoryError
. The cause is this bit of code
cider-nrepl/src/cider/nrepl/print_method.clj
Lines 37 to 40 in 247071b
(def-print-method Atom c | |
"#atom[" | |
(pr-str @c) | |
(format " 0x%x]" (System/identityHashCode c))) |
The pr-str
being the problem here.
A short side note on how the problem manifests: The shadow-cljs UI Inspect lets you inspect objects of any size, so for example the full shadow-cljs runtime state, which with a build running can easily reach gigabytes when printed. It does so by using a LimitWriter, i.e. a Writer that stops after a certain amount of bytes. This is exactly to prevent large objects blowing everything up, or making everything slow, when a Human could never look at the value in full anyways.
To try you can run shadow-cljs clj-repl
then (tap> shadow.cljs.devtools.server.runtime/instance-ref)
. With the cider-nrepl middleware installed this will be very very slow in the UI, without it is snappy. The UI is at http://localhost:9630/inspect.
The fix here would be to not use pr-str
, but rather delegate the writer to print the object into the handled stream. The macro abstracts this away unfortunately in a way that basically requires rewriting the entire macro. The gist is to call (print-method @c writer)
, i.e. the writer that gets passed to the print-method
in the first place. It is generally not a good idea to start one print from another, as you are supposed to use the supplied Writer
.
I realize this is a bit specific to shadow-cljs and its LimitWriter, but I'd rather not do what is documented here
(def ^:dynamic *pretty-objects*
"If true, cider prettifies some object descriptions.
For instance, instead of printing functions as
#object[clojure.core$_PLUS_ 0x4e648e99 \"clojure.core$_PLUS_@4e648e99\"]
they are printed as
#function[clojure.core/+]
To disable this feature, do
(alter-var-root #'cider.nrepl.print-method/*pretty-objects* not)"
true)
as that would interfere with what a cider user might prefer. I'd also rather not start being defensive in the print mechanism for Inspect by binding this var.
It would be nice if the two uses of pr-str
in that file, get changed to properly delegate to the print-method
with the supplied Writer, as this is globally installed and affects everything.