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

Ignore exceptions on socket close #540

Merged
merged 1 commit into from
May 23, 2023
Merged

Ignore exceptions on socket close #540

merged 1 commit into from
May 23, 2023

Conversation

PerchunPak
Copy link
Member

The #422 overwrote #379 which had the same fix. Although, it was applied to __del__ method only, and the idea to add this try-except in close method was dismissed as we excepted to get this error only during garbage collection (which is not the case since #422).

Fixes #538.

@PerchunPak PerchunPak added type: bug Something isn't working area: protocol Related to underlying networking protocol labels May 10, 2023
Copy link
Member

@ItsDrike ItsDrike left a comment

Choose a reason for hiding this comment

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

I remember this being there before, and I removed it because it was completely undocumented. So 2 key things here:

  • Why Exception? Why not a more specific type?
  • Add comment explaining why it's necessary, what's causing the issue, as it doesn't seem to happen often.

And ideally, though I don't insist on this, add a test ensuring this handling works as expected in this scenario.

@PerchunPak
Copy link
Member Author

Actually, it was introduced in 2542913 (#56) and was intended to ignore AttributeError error (this is not the case after #273). The TODO to check what it actually ignores was added in 8868bd4 and then the try-except was removed in #273. (This was just a small research)

Why Exception? Why not a more specific type?

I am unsure that we care about any exceptions there. I think that it's something wrong with the user OS, but who cares, the socket is used and needs to be only closed. So if the socket failes to close, and we got all info that we need - let's just ignore that.

And ideally, though I don't insist on this, add a test ensuring this handling works as expected in this scenario.

Looking at #140, I'm unsure that mocking socket is a good idea.


Wow, the project is so big and old...

@kevinkjt2000
Copy link
Contributor

This gives me flashbacks to the reason I started maintaining mcstatus. The first PR I merged looked very similar to this.

@ItsDrike
Copy link
Member

ItsDrike commented May 12, 2023

I am unsure that we care about any exceptions there. I think that it's something wrong with the user OS, but who cares, the socket is used and needs to be only closed. So if the socket failes to close, and we got all info that we need - let's just ignore that.

Actually it's pretty important to ensure that the OS recognizes the socket as closed, and removes that resource from the process. That's because most kernels have limitations for processes, such as a maximum amount of file descriptors, which sockets do take up (see: #337). This can then end up causing weird errors like "OSError: Too many open files", when creating a new socket connection.

Because of that, I'm still not sure it's such a good idea to just blindly ignore all exceptions here, and it's probably worth investigating why this actually occurred, and looking into it a bit more.

@PerchunPak
Copy link
Member Author

Errno 107 means that the socket is NOT connected (any more).

https://stackoverflow.com/a/4668710

Would it be okay to something, like here?

@ItsDrike
Copy link
Member

ItsDrike commented May 13, 2023

Yes! That looks like a much better way to handle this, with the rest of the exceptions still getting raised, but do notice that this handling is done in socket.shutdown, not in socket.close, instead, close is still called without any handling below.

So I suppose what's going on is that if some internal flag in the socket instance, representing connection status is on. When close is then called, if this flag is on, shutdown is likely getting called before the actual closing, to properly send the disconnection packets. So, I suppose that if it's done manually like this, that flag gets toggled, even if we get an exception later. So calling close afterwards is safe, and that's what then makes the syscall, telling the kernel to remove that socket from the process.

I quite like this solution, but I'm not sure if I'm correct about this internal flag, if this is the case, we can use this solution.

@PerchunPak
Copy link
Member Author

We shutdown socket too, just in other function.

@ItsDrike
Copy link
Member

ItsDrike commented May 13, 2023

Then the handling should be done in that function, not in the exit functions, and only on the shutdown.

When handling this on the close function itself, if this error occurs, the socket doesn't get closed, the exception is raised from the shutdown line, so we never even get to the line below calling close. The exception from shutdown is handled and ignored, and the socket remains attached to the process.

@PerchunPak PerchunPak linked an issue May 14, 2023 that may be closed by this pull request
@PerchunPak
Copy link
Member Author

Sorry for the delay, VRChat is more interesting that I excepected

Copy link
Member

@ItsDrike ItsDrike left a comment

Choose a reason for hiding this comment

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

No worries, we're all just volunteers here.

Looks good, other than the comment in the except line

mcstatus/protocol/connection.py Outdated Show resolved Hide resolved
@ItsDrike ItsDrike merged commit bf8c1b5 into master May 23, 2023
8 checks passed
@ItsDrike ItsDrike deleted the try-to-fix-538 branch May 23, 2023 09:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: protocol Related to underlying networking protocol type: bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Query throws a "OSError: [Errno 107] Transport endpoint is not connected" [Errno 57] Socket is not connected
3 participants