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

Feature/change window size request for ssh client #1062

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

glenkleidon
Copy link

Implemented ShellStream.WindowChangeRequest by surfacing existing implementation in (private) _channel::IChannelSession.

Copy link
Member

@drieseng drieseng left a comment

Choose a reason for hiding this comment

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

Can you also contribute a small self-contained application that excercises this new method?
That application should signal an error if that method was not called exactly as expected (eg. if rows and columns where switched in our implementation).

I'd also like to discuss the name of this method. Are there better alternatives (eg. ChangeWindow)?

/// <returns>true when change is successful, or false when channel is NOT open or the request </returns>
public bool WindowChangeRequest(uint columns, uint rows, uint width, uint height )
{
if (_channel==null || !_channel.IsOpen) return false;
Copy link
Member

Choose a reason for hiding this comment

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

Please have it throw an ObjectDisposedException when _channel is null, and an InvalidOperationException if the channel is closed. Please document this as such and add corresponding unit tests.

I would've prefered to have the method on ChannelSession also throw if the channel were closed, but that would be considered a breaking change. That method currently either throws or returns true, never false. It also returns true if the channel is closed 😌

Copy link
Author

Choose a reason for hiding this comment

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

This method is essentially a wrapper for SendWindowChangeRequest which returns a boolean. It makes sense that this method also returns boolean. Nothing will break if the request fails, so therefore it is not exceptional that the method fails.

I always ask myself - as library developers, can we KNOW that it is Exceptional that a method is called when in the wrong state or is it simply unexpected. Often the answer is that you can't know the answer because we don't know the context of how the method is being used. The developer using the library will know if the situation is exceptional and can throw if it is. All we need to do is say whether or not it succeeded.

If you throw an exception in a library - it has to be fundamentally wrong to do so. In this case, I don't think it is - it is merely unexpected and of no consequence. There wont be any data coming back to be "in the wrong shape" so it wont matter that the method failed. There might be an argument for Throwing the exception if the channel had never been opened, but as this happens in the constructor that is not possible.

The scenario that comes to mind is, in the CanClose Event of a Desktop App, OR the Close browser event, the shape of the window may change during clean up. If that happens, the event to change window shape MAY still be attached causing the event to fire when the channel has already closed. It is much simpler to handle for the developer if the method does not throw an exception and the unexpected event can be ignored. With an exception, in order to properly clean up, the developer must remember to unsubscribe to events or risk an exception being raised when it is of no consequence.

Returning false allows to the developer to decide if failed call to change window size is exceptional. So I think returning a boolean is the right call here.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, ChangeWindow might be a better name. Happy to do this. Should I proceed?

Copy link
Author

Choose a reason for hiding this comment

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

Ok changed in commit [61d5324]

Copy link
Author

Choose a reason for hiding this comment

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

With regards to an example application - I have a fully worked example in branch glenkleidon:feature/add_vs_2022_solution

Should consider doing a pull request on that one but I need some help with a failed test case.

Copy link
Author

Choose a reason for hiding this comment

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

Actually the blocker is the failed test case on #1024

/// <param name="width">New screen width in Pixels</param>
/// <param name="height">New screen height in Pixels</param>
/// <returns>true when change is successful, or false when channel is NOT open or the request </returns>
public bool WindowChangeRequest(uint columns, uint rows, uint width, uint height )
Copy link
Member

@drieseng drieseng Dec 11, 2022

Choose a reason for hiding this comment

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

Given the rationale below, we could consider having this method return void.
I prefer to discuss this with other team members before we decide how to proceed with this.

Please remove the extra whitespace before the closing parenthesis.

Copy link
Author

Choose a reason for hiding this comment

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

ok removed white space. commit [ec60725]

Copy link
Author

Choose a reason for hiding this comment

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

Should return false as it is not necessary to throw an exception in this case is often of no consequence that the method does not succeed. Also it is a wrapper for the underlying method which returns boolean.

{
var shellStream = CreateShellStream();
_channelSessionMock.Setup(s => s.IsOpen).Returns(true);
_channelSessionMock.Setup(s => s.SendWindowChangeRequest(
Copy link
Member

Choose a reason for hiding this comment

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

Not very useful since SendWindowChangeRequest(...) always returns true, but let's discuss.

Copy link
Author

Choose a reason for hiding this comment

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

Hmm, I dont think SendWindowChangeRequest SHOULD always be true. For example a change to size of 0,0,0,0 should fail and probably will on some pty implementations.

_channelSessionMock.Setup(s => s.SendWindowChangeRequest(
It.IsAny<uint>(), It.IsAny<uint>(),
It.IsAny<uint>(), It.IsAny<uint>())).Returns(true);
Assert.IsTrue(shellStream.WindowChangeRequest(80, 25, 0, 0));
Copy link
Member

Choose a reason for hiding this comment

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

Please also verify that SendWindowChangeRequest(...) was actually invoked (once).

@scott-xu
Copy link
Collaborator

Would you mind resolving the conflicts? @glenkleidon

@glenkleidon
Copy link
Author

glenkleidon commented Feb 13, 2024 via email

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.

None yet

3 participants