Skip to content

cider Atom print-method bricking shadow-cljs UI Inspect #819

@thheller

Description

@thheller

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

(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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions