Fork me on GitHub
#nrepl
<
2019-10-14
>
cfleming06:10:28

I’m having a problem implementing support for nrepl.edn in Cursive, although I’m not sure if this is an nREPL problem or a piggieback one.

cfleming06:10:08

I thought I had implemented the support, but when I try to test piggieback, I get:

Connecting to local nREPL server...
nREPL server started on port 52466 on host 127.0.0.1
Clojure 1.10.1
(require 'cljs.repl.nashorn 'cider.piggieback)
=> nil
(cider.piggieback/cljs-repl (cljs.repl.nashorn/repl-env))
Execution error (IllegalStateException) at cider.piggieback/cljs-repl (piggieback_impl.clj:168).
Can't change/establish root binding of: *cljs-repl-env* with set

cfleming06:10:45

I found a couple of issues about this, but they were either about using very old versions of various things, or about using trampoline with leiningen.

cfleming06:10:40

I’m establishing my server like this:

`(do
   (-> (File. ~(.getCanonicalPath init-file))
       (.deleteOnExit))
   (try (require 'nrepl.server 'nrepl.config 'nrepl.cmdline)
        (catch Throwable t#
          (println "Error loading nrepl.server:"
                   (or (.getMessage t#) (type t#)))))
   (try
     (let [config# (merge {:host "127.0.0.1"
                           :port 0}
                          nrepl.config/config)
           {:keys [port# bind# handler# transport# greeting#]} (nrepl.cmdline/server-opts config#)
           server# (nrepl.server/start-server
                     :port port#
                     :bind bind#
                     :ack-port ~ack-port
                     :handler handler#
                     :transport-fn transport#
                     :greeting-fn greeting#)
           port# (:port server#)]
       (println "nREPL server started on port" port# "on host 127.0.0.1"))
     (catch Throwable t#
       (println "Error starting server:"
                (or (.getMessage t#) (type t#))))))

cfleming06:10:07

deps.edn:

{:deps    {org.clojure/clojurescript {:mvn/version "1.10.520"}}
 :aliases {:repl {:extra-deps {nrepl/nrepl {:mvn/version "0.6.0"}
                               cider/piggieback {:mvn/version "0.4.2"}}}}}

cfleming06:10:28

nrepl.edn:

{:middleware [cider.piggieback/wrap-cljs-repl]}

cfleming06:10:30

I’m not directly invoking nrepl.cmdline for everything, but I am reusing most of its logic, in particular for creating the handler from the configured middleware.

cfleming06:10:37

Am I missing something obvious?

cfleming07:10:34

Ok, one problem was that nrepl.edn should have been .nrepl.edn, so the middleware wasn’t being found. However even after fixing that I’m still having the same problem.

cfleming07:10:58

I’ve debugged this, and the piggieback middleware does seem to be being applied to the handler correctly, which means I’m pretty much out of ideas.

bozhidar07:10:05

Hmm, if the handler is correct I can’t imagine how this wouldn’t work.

cfleming07:10:39

I’m going to try just calling nrepl.cmdline directly and passing the args as if I were calling -main, and see if I’m missing something subtle.

bozhidar07:10:46

Did you try it with some other middleware as well?

cfleming07:10:58

No, is there an easy one to test with?

cfleming07:10:17

Is there an echo middleware or something like that?

bozhidar07:10:17

There’s not, but I guess it’s not a bad idea. 🙂 There a few pretty basic ops in cider-nrepl, though - e.g. classpath.

cfleming07:10:39

The problem is I don’t have anything in the client for sending custom messages.

cfleming07:10:58

I’m going to try calling nrepl.cmdline first, which is an easy test.

bozhidar07:10:07

Oh, got it. I always assumed you had some generic support for custom messages.

cfleming07:10:29

I don’t really use custom messages at all, so I’ve never had the need.

cfleming08:10:23

Ok, so if I just call nrepl.cmdline directly, that works.

bozhidar08:10:06

That definitely surprised me, as your code looked legit to me, but I’m glad to hear we didn’t break something. 😄

cfleming08:10:18

Yeah, it’s weird. I think I’ll continue just calling that directly, but it’s definitely odd.

cfleming08:10:44

So I’m obviously missing something either subtle or obvious.

cfleming08:10:45

I think I’ll just keep doing that so that Cursive will interop better with all the related nREPL tooling, and things like .nrepl.port should just work.

bozhidar08:10:04

I agree. I’d also welcome some feedback on the current state of the nrepl.cmdline API, which I consider experimental at this point. Obviously without having clients of it around it was hard to assess if we got it right or not. 🙂

cfleming08:10:00

This is currently the extent of my use of it:

(try (require 'nrepl.cmdline)
               (catch Throwable t#
                 (println "Error loading nREPL:"
                          (or (.getMessage t#) (type t#)))
                 (System/exit 1)))
          (nrepl.cmdline/-main "--ack" ~(str ack-port))

bozhidar08:10:36

Ah, got it. I thought you went more granular than that. 😄

bozhidar08:10:28

One bit of feedback I see is that maybe we should suppress exceptions coming from -main.

cfleming08:10:12

It would be nice to be able to hide the port ack message.

bozhidar08:10:20

Can you file a ticket about this?