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

Implement reconnections with screen #25

Merged
merged 19 commits into from
Nov 22, 2022
Merged

Implement reconnections with screen #25

merged 19 commits into from
Nov 22, 2022

Conversation

code-asher
Copy link
Member

@code-asher code-asher commented Sep 14, 2022

This resolves issues with unexpected "junk" output when reconnecting.

It might be easiest to review by commit, especially after the second one that reverts the original implementation.

I added a Nix flake to provide screen for testing.

See #24 for more details.

Going to add an alternate screen test next.
This partially reverts commit 9120171.

The new method using screen will not share processes which is a
fundamental shift so I think it will be easier to start from scratch.

Even though we could keep the UUID check I removed it because it seems
cool that you could create your own sessions in the terminal then
connect to them in the browser (or vice-versa).
The output test waits for EOF; modify that behavior so we can check that
certain strings are not displayed *without* waiting for the timeout.
This means to be accurate we should always check for output that should
exist after the output that should not exist would have shown up.
This makes it easier to test reconnects manually.
This way you do not need a subsequent resize and we can have the right
size from the get-go.
server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
I think this helps make the tests a bit more concise.
Since the server closed the socket the caller has no chance to close
with the right code and reason.

Also abnormal closure is not a valid close code.
Without waiting for the copy you can sometimes get "file already
closed".  I guess process.Wait must have some side effect.
Copy link
Member

@kylecarbs kylecarbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good to me.

What happens if I don't have screen? I think it'll just fail right now, but the optimal in my mind is to have it still work...

@code-asher
Copy link
Member Author

code-asher commented Sep 30, 2022

Without screen it will run like it did way back when without any reconnection logic (so disconnecting will lose your session).

s = NewSession(id, command, execer, options)
srv.sessions.Store(id, s)
go func() { // Remove the session from the map once it closes.
defer srv.sessions.Delete(id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The delete happens outside the context of holding the mutex, since it is on a different goroutine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I was not sure if locking around the delete would change much functionally since sync.Map is threadsafe so I left it out. Vaguely I was thinking if loading and deleting happens at the same time whether it blocks on the mutex we add or the mutex internal to sync.Map it would be more or less equivalent.

I think there might be a gap in my logic though. And it does make sense to be explicit even if not.

session.go Outdated Show resolved Hide resolved
session.go Outdated Show resolved Hide resolved
Copy link
Contributor

@spikecurtis spikecurtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

I don't really understand the Nix stuff, but I don't think that should block this PR

client_test.go Show resolved Hide resolved
@code-asher
Copy link
Member Author

code-asher commented Nov 21, 2022

I am down to move the Nix stuff into another PR. It is a decent way to get all the required system dependencies at the right versions for a project without having to install them by hand or edit your image (in this case, screen). We have a Nix flake in v2 so I used that as precedent 😄

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

Successfully merging this pull request may close these issues.

3 participants