-
-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preserve :actual-value of evaluation in middleware pipeline #99
Comments
Ahh it seems one reason this may have been missed is that it looks like some of this was recently changed in #12 |
@RickMoynihan The changes in #12 were simply cosmetic - a hardcoded function for printing the result was made configurable. It's still probably most prudent to simply insert this middleware before
We can do something like this, but there's a chance it can break some clients as a complex EDN response might be hard for them to swallow. I'll have to take a closer look at this. |
Specifically what clients are you thinking @bbatsov? The idea is that the Are there any middlewares that we know of that look at all the keys from the response map? I also suggested to Rich that it might be worth providing a new op:
With the idea being that a client could send a form to datafying-eval and have the server call datafy on the response before returning it. If you think it's a good idea I can create a new ticket for it. |
I recall at least in the early days of CIDER it's bencode parser would sometimes explode when faced with complex metadata EDN maps. And in general you can even represent everything can be in EDN in bencode, so this has to be kept in mind as well.
That's kinda hard to achieve as
There are many middlewares that simply inspect and modify a response map, but the real problems is what you end up sending to the clients in the end of the day. I'm guessing another option might be to store the EDN results server-side and have some op to retrieve them. I have to think more about this. Rich's idea seems reasonable as well. All of the above would be greatly simplified for clients of the upcoming EDN transport, but of course you'll need clients who can work with EDN. :-) I'd also like to hear what @cgrand, @SevereOverfl0w and @alexander-yakushev think about this. |
Without working with nREPL closely before, I'd say I never understood why it is so trigger-happy about turning the result values into a string early. So I think the approach Rick suggests is sensible. I would perhaps think of another name for it,
Couldn't there be some non-optional "middleware" that takes care of it and cannot be disabled? |
Likely this wasn't always the case, as there are some historical references to
Yeah, I don't like
Yeah, this can certain be done. It would just have to be a middleware that comes after |
Evaluation binds Something to think about is whether pr-values was an architectural mistake. Maybe the transport should be responsible for this behavior? That is something that always happens at the "end". |
The big problem was (and still is but to a lesser extent) that printed values are not always readable (let alone EDN-readable) and even when they are readable, you lose information (e.g. class vs symbol). I know: I had to work around that for Unrepl. That's why REBL is local (same JVM) too: it's just easier. I'v started working on simple extension to Unrepl EDN representation to fully support datafy/nav, so you won't have to use a swing UI to get datafy/nav. |
I strongly disagree. It's orthogonal to transport responsibility. Current transport definition is already complected: why does |
I agree. Likely this was something "to be improved" that simply never happened. I know Chas envisioned non-socket transports, so it certainly makes sense in principle to have clear separations of transports and representation.
Great point. |
EDIT: this comment is misleading/plain wrong; please see below. @RickMoynihan We use the same technique of injecting a wrapping transport in both the However @SevereOverfl0w raises a very good point:
Your middleware does not actually interfere with (let [{:keys [session]} request]
(get @session #'*1)) Since the session middleware ensures serialised execution this is safe to do even in the face of concurrent eval requests being made. |
@cichli Seems we can close this one, right? I guess we’ve decided that we don’t really need to do anything about it. |
I meant to follow this up, I'd tried to do what @cichli said but had some trouble getting it to work. I'm not sure what happened (I suspect I wired things up wrong) but IIRC it looked to me like the middleware I wasn't able to access the I suppose I'll need to try set this all up again, and maybe push it somewhere for someone to look at if I still can't get it to work. |
Looks like this PR should fix the issue RickMoynihan/nrebl.middleware#17. |
@RickMoynihan indeed, my comment above is incorrect on two counts. Sorry about that.
I opened the above linked PR to take the approach of enforcing the correct middleware ordering and using |
I've been implementing a middleware that can send evaluation results to the new cognitect REBL tool. It's still early stages but it essentially works; with some rough edges to iron out.
Rich Hickey recently asked on slack clojurians on the
#rebl
channel how it works. It seems when he'd looked into supporting REBL in nrepl he didn't think it was possible in the general case due to nrepl representing the result of the evaluation as a string.REBL makes use of the new clojure 1.10RC5 protocol functions in metadata extensions, and therefore having a string
:value
means these are lost if they're read back in; presumably resulting in a degraded experience for objects which can't have a simple print representation. Instead Rich said he thought it would be beneficial to have an:actual-value
also flow through the middleware response pipeline which would allow tools like nrebl.middleware and REBL an opportunity to do more than reading a string back would enable.The conversation ended with me saying I'd approach the nrepl maintainers to chase this up and see if we could introduce an
:actual-value
in the response maps in interruptible-eval, in addition to the current:value
. The difference being that:actual-value
would be the raw value until it gets to the wire; at which point it would be discarded... whilst:value
would be serialised over the wire.Before writing this though, I thought I'd check back at my implementation and the nrepl code to see how it worked; and I realised that I'd been mistaken and that nrepl wasn't giving my middleware a string at all. I'd simply forgotten about the hour I spent trying to inject middleware between interruptible-eval and pr-values!
So I believe my nrebl middleware is working correctly; though I'm not 100% sure if I'm reliably inserting myself between the two middlewares or not (if you can think of a better way for me to do it I'd appreciate it - see here).
So the good news is that it seems I can make my middleware work without introducing an
:actual-value
to nrepl. However it also seems like it might also be a good idea to provide a value intended for inprocess middlewares to intercept the true return value and not just a printed one. It seems this might be quite trivial by simply adding a new:actual-value v
kvp here in addition to the existing:value
which I'd propose is left as is for backwards compatibility.Does this sound sensible? I've only begun studying nrepl's code, so could well be missing something.
The text was updated successfully, but these errors were encountered: