nrepl 2026-08-27

I would like to do something like Drawbridge, but with SSE transport (no latency as with polling, but works via http proxies etc), and I would like it to use an alternative nrepl server (the Babashka one). I'm trying to make it work, but I'm curious if other people have tried something similar that I can learn from

Ok I have a proof of concept of the Babashka nrepl server wrapping. I guess it could be any nrepl server for that matter. Had to replace the writer function https://github.com/nrepl/drawbridge/blob/master/src/drawbridge/core.clj#L125 and bring my own client. I think the SSE transport is a bit more involved. So I'll first make it work with the polling option

Ok I have this setup working via Cloudflare (no sse yet). There are still some hiccups and timeouts that I don't understand (also locally). So still wip

Thinking about using drawbridge to nrepl into a k8s cluster. Whats your usecase? Any idea how to pin the session to a specific pod when replicas > 1?

Maybe your load balancer has something like sticky sessions with AWS?

My usecase is having access repl in "production" over http. Alternatively I could use an ssh tunnel, but I want to close all ports and let Cloudflare handle the access. But I guess I could also use something like tailscale and an ssh tunnel. I don't know, i'm just curious i guess

👍 1

Then the client would have to support cookies set by the server - no?

The Drawbridge client part handles that I believe

(via clj-http-client)

Ah interesting. We'll see if our ingress supports sticky sessions.

The Drawbridge implementation uses sessions (and thus) cookies to https://github.com/nrepl/drawbridge/blob/master/src/drawbridge/core.clj#L127 and having a unique client and transport for each of them

👍 1

So drawbridge would have to map nrepl sessions to http sessions?

Yeah exactly that's what it does. I tried to work without it while testing and I believe that bit me quite quickly so it is probably a must

Now I'm trying to get SSE to work for better latency and less server load. I believe it is not too hard, but need to figure out how things work exactly

Are you the author of drawbrige?

No @bozhidar (the maintainer) and I believe @cemerick the original author

I'm guessing drawbridge is especially interesting on dynamic bigger clusters where machines come and go and it is harder to ssh in (if even allowed)

Another thing i'm thinking is babashka/sci can be used to wrap existing CLJ environments to restrict the repl's power. I have this running locally as well

But when pods come and go you will struggle with the state in the jvms you're losing. So even when the nrepl session gets redirected to a new pod you'll be in a new fresh state. Its hard to 'replay' latest evals to reach that state again. Any ideas on that?

(Sorry this goes off topic a little 🙂)

Yeah that's also true. If you need the state of a specific instance. Maybe there are sticky sessions implementation that allow you to aim where you end up. In my experience the the instances with autoscaling even on a high scale still have a life span of 24 hours at least (depending on scaling pattern and traffic). So still gives you some time

Ah for replaying you mean, maybe work with random seeds per request? So everything is deterministic by that random seed

I never reached the point that i was doing it in production but I was working on a system that I tried to make simple to reason about and by using random seeds to make the whole flow replayable. Even with random requests as i was storing the body etc

So then you need to include things like time, uuid etc

No sorry wrong word. I meant what would have to be done to reach the same state ( the one of the shut down pod) in the new pod. One would have to fo the same evals again. And not even that works. Its just impossible to do the same things twice ..

Oh interesting. Replayable commands/evals? Haven't thought of that. Ok, got to go. Bb

👍 1

> Its just impossible to do the same things twice .. Yeah also my experience and things add up in bigger clusters, higher scale, more deploys etc. That's why I looked into this because we had many "random" things happening that were hard to understand without being able to replay it, or at least inspect. We got pretty far in inspecting, replaying only locally with synthetic data based on observations from production

If something happens often enough (and you can reach the same machine again), you can use inline defs to capture certain data and then use that to inspect/refeed it into functions later

Why SSE and not websockets (if your proxy handles that)?

I did something similar to this: https://github.com/ivarref/yasp and example usage: https://github.com/ivarref/yasp/tree/main/aleph-example It's not great but it has worked for us. (Our proxies does not do WebSockets)

(single node / just a container setup here)

> Why SSE and not websockets (if your proxy handles that)? I think if you can do the same with SSE then that is much easier to operate. I will have to see if SSE gives a good enough experience to prefer it over websockets here. But I have been playing with SSE a lot for other things and most of the time it works seemless. Cloudflare does support websockets, but it is some additional configuration where SSE just works.

👍 1

The only thing I realize now is that SSE doesn't have a standard implementation in Ring like websockets. So it might be harder to have drawbridge offer one ring handler that will work in most Clojure servers.