Skip to content
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

Support for multiple connections #16

Open
technomancy opened this issue Dec 7, 2016 · 37 comments
Open

Support for multiple connections #16

technomancy opened this issue Dec 7, 2016 · 37 comments

Comments

@technomancy
Copy link
Contributor

It seems like right now monroe only supports connecting to a single nrepl instance at a time.

Are you interested in adding support for more than one active *monroe* buffer, or is it better to use separate Emacs instances for that?

@sanel
Copy link
Owner

sanel commented Dec 7, 2016

I was planning to add it (made a few attempts), just didn't have enough time to complete it. However, if you are able to do it, keeping the code simple, I'll be happy to accept the patch :)

@technomancy
Copy link
Contributor Author

Good to know; thanks. No promises, but I might take a shot at this at some point.

@bbuccianti
Copy link
Contributor

I'm thinking of making an attempt too. Maybe we can discuss a little about how to do it?

@sanel
Copy link
Owner

sanel commented Sep 14, 2019

Feel free @bbuccianti :) Maybe check inferior-lisp mode (inf-lisp.el in Emacs) for multiple processes support.

@sogaiu
Copy link

sogaiu commented Oct 4, 2019

@bbuccianti

For reference, if you want to see an existing attempt for a socket repl-based thing with multiple connections, I've had some luck w/:

It's been working pretty well for me so far.

I started with sesman, but decided it was much more than I needed.

@bbuccianti
Copy link
Contributor

bbuccianti commented Nov 27, 2019

@sanel @technomancy @sogaiu

Can you help me test this?

https://github.com/bbuccianti/monroe/

I'm sure there is a lot of ways to improve it, please help me!

@sogaiu
Copy link

sogaiu commented Nov 28, 2019

Do you mean the multiple-connections branch?

https://github.com/bbuccianti/monroe/tree/multiple-connections

@bbuccianti
Copy link
Contributor

This is the correct commit:

bbuccianti@38a1488

@sogaiu
Copy link

sogaiu commented Nov 28, 2019

Had success interacting with 2 separate processes from within a single emacs instance.

Opened two files -- each one from a different project -- ran M-x monroe in each and tried M-x monroe-eval-region. Seems to work 👍

IIUC, there is at most one connection per project and at most one process per project. Is that correct?

@bbuccianti
Copy link
Contributor

bbuccianti commented Nov 28, 2019

Yes, it's using the project folder as a pointer concatenating it with monroe and monroe-conn buffers.

I've created a pull request #33

@sanel
Copy link
Owner

sanel commented Nov 28, 2019

Thanks @bbuccianti for your work and @sogaiu for fast response!

Is #33 will add support for multiple connections? Title of PR confuses me :)

Also, does it handle reading .nrepl-port from project tree?

@bbuccianti
Copy link
Contributor

It still uses monroe-locate-port-file.

The only change is that instead of naming the buffers *monroe* and *monroe-conn* I conj the project folder to it. Then, when you try to send code to the nrepl it searches for the correct buffers using the project folder.

@bbuccianti
Copy link
Contributor

@sanel I just improved the title of the PR

@sanel
Copy link
Owner

sanel commented Nov 28, 2019 via email

@bbuccianti
Copy link
Contributor

I can't reproduce the issue with prompt. Maybe I'm evaluating trivial things, but seems to work fine for me.

bbuccianti@05b37d9

Now it's using the host:port combination to name buffers and also call (monroe-disconnect) before trying to attempt another connection.

Let me know!

@sanel
Copy link
Owner

sanel commented Dec 5, 2019

Thanks @bbuccianti for your work so far! However, I still have issue with prompt. What Emacs are you using?

Here is how to reproduce it:

  1. Run lein repl somewhere.
  2. In new Emacs session, run monroe, it will ask for connection.
  3. After you connect, you will see prompt. Enter something like (+ 1 2 3) in REPL. It will print result, but prompt is no longer visible.

Here is how it looks for me:

user=> (+ 1 2 3)                                                                                                                                                                                                    
6
;; no prompt here                                                                                                                                                                                                                   
(println "abc")                                                                                                                                                                                                     
abc
;; no prompt here

@bbuccianti
Copy link
Contributor

Are you using this? #33

I'm currently using GNU Emacs 26.3 (build 1)

@sanel
Copy link
Owner

sanel commented Dec 5, 2019

Yes, using PR #33 and same Emacs version. Tried even with emacs -Q.

Can you try loading PR with emacs -Q please?

@bbuccianti
Copy link
Contributor

Well, that works for reproducing the issue. Any suggestion on how to fix it?

@sanel
Copy link
Owner

sanel commented Dec 5, 2019

I'm curious how it worked for you - maybe some package "fixed" that :) This happened before for me and I believe it is up to comint-mode now as well (comint can break in weird ways if you messed up options or processes). I'll check this one.

@bbuccianti
Copy link
Contributor

I've tested with commit 2f472fd and it's not working in emacs -q !

@sanel
Copy link
Owner

sanel commented Dec 6, 2019

Hm... does it work for you if you revert to this: a7cf37e ?

@bbuccianti
Copy link
Contributor

bbuccianti commented Dec 7, 2019

Yeah! Can confirm that commit a7cf37e it's working as expected.

Also I want to tell that seems like a callback done with monroe-make-response-handler isn't running with the "done" status. Then monroe-requests isn't cleaned so the prompt is never added again.

But is really strange, because status is clearly truthy but can't go inside the (when status ;cleaning) code. I'm really new to those kind of callbacks and don't know really how monroe-dbind-response is doing is magic, but I'm learning a lot. Would be great if you @sanel can give some advice in how to debug that part.

Thanks!

@bbuccianti
Copy link
Contributor

@sanel no advances on this?

@sanel
Copy link
Owner

sanel commented Jan 30, 2020 via email

@bbuccianti
Copy link
Contributor

I force-pushed to #33

Thanks @sanel

@sanel
Copy link
Owner

sanel commented Mar 21, 2020

Thanks @bbuccianti ! Will take a look :)

@sanel
Copy link
Owner

sanel commented Jul 3, 2020

Implemented with #33

@sanel sanel closed this as completed Jul 3, 2020
@sanel sanel reopened this Jul 3, 2020
@sanel
Copy link
Owner

sanel commented Jul 3, 2020

Sorry @bbuccianti but this still doesn't work. To demonstrate:

  • Emacs 26.3
  • In separate run new nrepl server with lein repl
  • From emacs, run monroe and connect to nrepl address
  • In monroe buffer, enter + and press enter
  • It will print #object[clojure.core$_PLUS_ 0x4e0e22f4 "clojure.core$_PLUS_@4e0e22f4"] but prompt is not shown.

Worse, with multiple connections, it mess up where evaluation should go. To reproduce:

  • Run 2 different nrepl servers it separate terminals.
  • Connect from Emacs to both of them (running monroe and entering their addresses).
  • Enter + in one monroe buffer, it will evaluate in second.

How you manage to get this working?

@sanel
Copy link
Owner

sanel commented Jul 3, 2020

@technomancy after 1c2559b prompt is no longer shown when you enter something like + in fresh monroe session. What is reasoning behind this change?

Does it work for you?

@bbuccianti
Copy link
Contributor

bbuccianti commented Jul 3, 2020

I think it's my error. I assumed that you would open a monroe session from a project folder. So it's searching for the .nrepl-port file in order to get the correct buffer to send eval string to the correct process.

That's why connecting from another places it's screwing everything. I don't know how to solve that problem (yet), I need to think more.

Maybe we can add a prompt in order to ask for the project folder when it doesn't find that .nrepl-port file?

@bbuccianti
Copy link
Contributor

I'm testing b540e13 in Emacs 28.0.5 and seems to resolve ok different connections, without the need of .nrepl.-port. I read now that it tries to get port from the .nrepl-port file, if it doesn't find one it is extracted from the buffer. That's way the buffer now it's called "monroe: %s" being %s the host:port.

Maybe it's an issue with Emacs 26.3 version? But I think @technomancy was using that version of 25, I don't remember exactly.

@sanel
Copy link
Owner

sanel commented Jul 3, 2020

I had the same issue with 26.1 I think... we must support older versions as well, including currently stable one :)

Now, I haven't dig deeper into the code, but the strategy of reading ports should be different IMO. When new connection is requested, it should only read .nrepl-port file to suggest host and port (as was doing before). After that, it should encode those inside buffer name.

I'm curious, how clojure-mode buffer (buffer where clojure code is) knows to which monroe repl to send code?

@technomancy
Copy link
Contributor Author

@sanel re: 1c2559b the old logic was only to print the prompt when a message was received that did not contain certain keys in it; however, IMO this was taking advantage of an implementation detail in the reference implementation of the Clojure nrepl server.

There is nothing inherent in "a message with no output" that guarantees it is equal to "the input you sent is done being evaluated"; it's just an accidental property that the one nrepl server happens to have, and other servers do not have. In that commit I made it based on whether there were any outstanding requests in the monroe-requests table, but that's no longer a good criteria now that multiple connections are possible.

Probably what it should have been based on from the start is when a message is received where the status field contains "done".

@bbuccianti
Copy link
Contributor

It's still the same approach. It reads from .nrepl-port or you can provide host:port or :port using localhost as default. Nothing changes there.

What changes is the name of the monroe buffer. Before it was monroe. Now with this change we create a buffer as monroe: host:port. And for the connection it's similar. It creates a monroe-connection: host:port.

In this way then, to return the correct buffer we use monroe-repl-buffer function. If you found .nrepl-host, it returns the monroe: host:port buffer, otherwise it's assuming you are in the monroe buffer and it extracts host:port from the buffer name.

@bbuccianti
Copy link
Contributor

I see an error that I can't fix. I can show you the output of both versions of Emacs 26 and 27, reactioning to the same input.

decoded: ((dict (id . 1) (ns . user) (session . a54cd27f-152b-4b2e-aa87-384597d4486b) (value . 5)) (dict (id . 1) (session . a54cd27f-152b-4b2e-aa87-384597d4486b) (status done)))
net-filter response: (dict (id . 1) (ns . user) (session . a54cd27f-152b-4b2e-aa87-384597d4486b) (value . 5))
response: (dict (id . 1) (ns . user) (session . a54cd27f-152b-4b2e-aa87-384597d4486b) (value . 5))
net-filter response: (dict (id . 1) (session . a54cd27f-152b-4b2e-aa87-384597d4486b) (status done))
response: (dict (id . 1) (session . a54cd27f-152b-4b2e-aa87-384597d4486b) (status done))
GNU Emacs 27.0.91 (build 1, x86_64-pc-linux-musl, X toolkit, cairo version 1.16.0) of 2020-07-03
Monroe connected.
decoded: ((dict (id . 1) (ns . user) (session . fec70c4b-59a9-4258-a884-c6e270720ae3) (value . 5)) (dict (id . 1) (session . fec70c4b-59a9-4258-a884-c6e270720ae3) (status done)))
net-filter response: (dict (id . 1) (ns . user) (session . fec70c4b-59a9-4258-a884-c6e270720ae3) (value . 5))
response: (dict (id . 1) (ns . user) (session . fec70c4b-59a9-4258-a884-c6e270720ae3) (value . 5))
GNU Emacs 26.3 (build 1, x86_64-unknown-linux-musl) of 2019-08-29

I'm trying to investigate why net-filter isn't called again.

@bbuccianti
Copy link
Contributor

I think I have a fix in #34

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants