Fork me on GitHub
#dev-tooling
<
2023-01-13
>
cfleming03:01:18

Hi folks, I’m working on Cursive’s nREPL implementation, to better support nbb and other related projects as discussed in https://github.com/nrepl/nrepl/discussions/273. I’m still planning to do some probing of the nREPL runtime at startup to detect some known environments (cljs, JVM clj, babashka etc), and then I’ll fall back to a generic nREPL client impl if they’re not found. However, this detection is hard for some REPL types (scittle, and some browser CLJS REPLs) where there’s a two-step REPL connection process - start an nREPL server, then the actual evaluation client connects to that, and then the editor can evaluate code. There’s nothing in nREPL at the moment that I’m aware of which allows the client to detect “this server is not yet prepared to evaluate”, and later on “this server is now prepared to evaluate” when the evaluation client connects to the server. It’s also not clear to me whether existing implementations just block the nREPL server until the websocket or whatever connects (looks like weasel does, but I’m not sure about scittle). Any suggestions on how to handle this cleanly? Do all current implementations just block such that eval should always work?

👍 2
borkdude08:01:13

I can make changes to scittle nREPL + websocket behavior if desired

cfleming09:01:40

I spent some time setting up test projects to play around with the current behaviour, but it needs some more work for me to have a good feeling for how it ought to work. I’ll probably put a comment in nrepl/275 afterwards for discussion.

mauricio.szabo18:01:15

I don't have a good answer either - what I do in Chlorine is that I send some detection code, and wait for a specific timeout, before I consider the REPL "disconnected". It's hard because I actually never saw any REPL that blocks eval - for ClojureScript I'm interfacing directly with Shadow-CLJS, that's also non-blocking (and only supported by Shadow, so I know it's CLJS 😄)

bozhidar14:01:41

> There’s nothing in nREPL at the moment that I’m aware of which allows the client to detect “this server is not yet prepared to evaluate”, and later on “this server is now prepared to evaluate” when the evaluation client connects to the server. I don't quite get this - if you connect to a running server it's already ready for evaluation. Is the question about waiting for a server you've started to be ready? (e.g. you start the server and you wait for the right moment to connect to it)

bozhidar14:01:31

If it's the latter - I think a simple thing to do is just wait for the console output that a server is listening for connections.

bozhidar14:01:52

There's also the --ack functionality which notifies one nREPL server that another is ready to accept connections. It was originally developed for Lein, but I think it's an overkill and no one ever used it much.

cfleming22:01:19

@U051BLM8F The case I’m thinking of is when the nREPL server is not actually doing the evaluation, but is passing the code on to another target for evaluation. These are mostly CLJS browser REPLs at the moment, but I could imagine others? Here, my nREPL client connects to the nREPL server, but the server is only proxying the eval requests to the browser. So if my client connects to the server before the browser does, the nREPL server can’t evaluate any code I send it.

borkdude22:01:46

Yes, this also applies to scittle. I can make changes to block the request until the websocket is connected or something.

cfleming22:01:53

I got distracted and haven’t managed to do proper testing of the other environments yet to see if they all block, or allow eval attempts before they’re available.

👍 2
bozhidar06:01:44

Got it. I keep forgetting about those use-cases as I'm rarely doing something with ClojureScript.