-
Notifications
You must be signed in to change notification settings - Fork 11
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 shared sessions #55
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this!!
I think there's a difference between parsing on remote vs local side - I don't think one is quite a superset of the other. Especially when it comes to interpolating local variables, as might be done if #53 is implemented.
I'd prefer to keep @remote
as it is, and have a plain function rather than the @remoterepl
macro for string-based REPL communication - there's really no need for this to be a macro if users are just passing a string.
I'd suggest we just make a shorter more convenient name for the run_remote_repl_command
function and add some overloads to default to stdout
and the current default connection.
Maybe call it remotecmd
or something? So you can have
mod = "YourModule"
remotecmd("%module $mod")
(Actually I'd prefer that all the "magic" non Julia commands like %module
had their own functions rather than going through the REPL string parser. So to set the module you could have RemoteREPL.remote_module(mod)
or something. But that could be a separate PR.)
107178b
to
a32e15f
Compare
Some summary for the force-push: I generally agree with your comments, so I removed
|
No problems. I like the current argument ordering anyway by analogy to other functions like
Well
Mmm I'd prefer tests added as part of the PR. Tests can kind of be a pain but they're so essential in the long run. It's easier to write them when the new stuff is fresh in mind and to be motivated to do it if you want to use the feature they are testing. Testing shouldn't need to be super extensive for this feature. Just a few tens of lines should be enough and the client-server setup already exists in |
98298a9
to
d9b8369
Compare
before going to 1.0, it would be nice to talk a bit about #56 Update summary
|
@c42f Hi Claire. If there are no issues with the PR, could you please merge it and maybe make a new release ? |
@c42f Are there any blocking points? Do you think we can merge that soon? |
I've fixed the conflicts by rebasing and pushing to the pull request branch. That also seems to have triggered CI. Can you have a look at what's gone wrong there? |
ouf. that's gonna be hard. Locally using
I will have to look closer to that when I find some time. Btw thanks for making me a collaborator :) |
Oof. I suspect I've seen that finalizer error before. Probably not your fault! It's hard to clean up the ssh tunnel cleanly when the process exists. (Unless there's a way to hook the REPL shutdown more cleanly?) This is a relatively hard package to test. |
As said. The problem was very obscure and I still don't understand what was the issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so I found a little time to look through this again.
My main comment is that the server and client should always exchange the protocol header (including PROTOCOL_VERSION
) before they start doing anything else. This is to allow some comprehensible error message for users when both sides of the connection are on different RemoteREPL versions.
src/client.jl
Outdated
@@ -140,6 +139,8 @@ function setup_connection!(conn::Connection) | |||
namespace=conn.namespace) | |||
end | |||
Sockets.nagle(socket, false) # Disables nagles algorithm. Appropriate for interactive connections. | |||
# transmit session id | |||
serialize(socket, conn.session_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to go after verify_header()
and you should increment PROTOCOL_VERSION
if you're making an incompatible change to the RemoteREPL protocol (such as adding a session ID)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. done that. send_header
and verify_header
now come first.
It's an incompatible change from protocol perspective, but all user code is still backwards compatible. If no UUID
is passed a random will be generated. I increased the PROTOCOL_VERSION
.
Equivalent to using the `%module` magic. | ||
""" | ||
remote_module!(conn::Connection, mod::Module) = remotecmd(conn, Base.stdout, "%module $(mod)") | ||
remote_module!(mod::Module) = remotecmd(_repl_client_connection, Base.stdout, "%module $(mod)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally these would not use string concatenation because the %module
just needs to be parsed again on the client side in order to send the :in_module
command. But doing that cleanly that would require a bit of refactoring to pull out the last couple of paragraphs of remotecmd()
into a separate internal function dedicated to sending already-parsed command tuples. So I leave it to you to decide what to do about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I see that. I don't think it's too much work but I would like it to keep it like that for this PR. I made an issue to not forget #69
@c42f pushed an update. magic protocol is checked first now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be good to go, I think
Should we make a v0.3.0 release ? If I have permissions and it's fine by you I can make one. |
This PR seems to have broken the SSH tunnel tests :-( They work for me before this PR, but not after. I can't remember exactly, but I think the SSH tests are not enabled in CI because getting the SSH server working in the CI environment wasn't finished. |
Redesign for #45
Novelties and summary
In #45 we discussed that it would be better to use the underlying protocol to change the module.
It became clear that this is easier done if shared sessions were supported.
So instead of directly solving my problem I tried to introduce multiple shared sessions.
As a result, module update for Pluto is now also more straightforward.
1.
session_id
Basically I introduced a
session_id
that characterizes everyServerSideSession
.The server holds all the sessions in a
Dict{UUID, ServerSideSession}
.Everytime a client connects, it send the session UUID it wants to connect to as the first thing.
2.
SessionSideSession
Now
SessionSideSession
is not described by a singleSocket
but a vector ofSocket
s, which is kept up to date.3.
@remoterepl
I need a way to still connect remotely and change the module, i.e.
%module ...
, without having a REPL available (like Pluto).@remote
support only command execution. Therefore I introduced@remoterepl
which gives access to the REPL magic commands for all clients.The question is.. why not collapse
@remote
to@remoterepl
, since the second is a superset ?4. Structural changes
I put all the
using
dependencies on the src/RemoteREPL.jl file.I find it much more readable this way and it also follows community conventions.
Pluto side
Pluto notebook should look something like this gist.
I am not sure how to avoid the updating every second, but don't focus on that; this is a Pluto issue/discussion.
Basically Pluto just uses
@remoterepl
to upgrade the module in a specific session.The core code boils down to
Test
Run the pluto notebook.
Open a julia kernel, add dependencies and do:
As you can see the remote client closely follows the changes in the Pluto notebook.
Let me know how that looks and I am happy to hear your thoughts!