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

autoPurge can throw an exception if the socket was closed without purging #154

Closed
schveiguy opened this issue Jan 20, 2018 · 14 comments
Closed

Comments

@schveiguy
Copy link
Collaborator

autoPurge should check if the socket is open before trying to read from it. I'm having this happen all the time now.

Not sure how to reproduce, as I'm not sure what condition makes the socket close (perhaps even mysql server itself closes it).

@schveiguy
Copy link
Collaborator Author

I am "simulating" the error by restarting the mysql server after a connection is connected.

I tried adding a check to see if the socket is open and returning from autoPurge before trying anything, but now instead of crashing, the server gets stuck. So that's not the only answer. Still investigating...

I would recommend adding a test to your test suite that restarts the mysql server while a connection is connected. This definitely can happen in practice.

@schveiguy
Copy link
Collaborator Author

More info: the call is failing I think due to already-buffered data. Still investigating.

@Abscissa
Copy link

Just a couple off-the-top-of-my-head ideas (don't have time to dig into this right now):

I wonder if maybe Connection's _open member is partly at fault here and should be eliminated in favor of directly asking the Socket if it's open (which, it appears Connection.closed() already does, but looks like there are some places that access _open directly, thus bypassing the call to ask the socket directly whether its open)

Also, the abstraction over Phobos sockets has a scope guard that closes the socket upon failure, but I notice the equivalent Vibe socket code lacks that. Maybe related to what you're experiencing?

@schveiguy
Copy link
Collaborator Author

OK, I figured out the issue. As I suspected, when autoPurge is called, if the connection is gone, it tries to purge all data anyways, causing an error. However, the state doesn't get reset.

My attempt to fix the problem was to just return immediately from autoPurge when the socket is closed (this is known to the socket). But unfortunately, connecting the socket doesn't reset all that state. So then it tries to autoPurge on the newly opened socket, thinking there is data to read, and it hangs waiting for data that isn't coming.

The reason I thought it may be already buffered data is because I stopped waiting for a response in my browser, and tried sending another request. For some reason it gets the "server packet out of order" error. I printed out the packet numbers and it got 31, but was expecting 1. I'm not sure how this happened, and it's definitely not a buffering issue, as the new connection is made by creating an entirely new object. Perhaps it's getting this same connection, and something weird is happening. It shouldn't happen that way, but I'm not sure what that problem is at this point. I'll just chalk it up to "I have no fucking clue what I was doing" ;)

I have since fixed figured out how to reset the state, so now I have autoPurge doing that if the socket is disconnected. PR forthcoming, but not this minute as I have to run.

@schveiguy
Copy link
Collaborator Author

One minor addition: I'll submit the PR, but I'm not 100% sure how the Phobos socket works, as I'm using vibe.d. So you should test the PR against that use case (simulate by restarting the mysql server).

@Abscissa
Copy link

Abscissa commented Jan 26, 2018 via email

@schveiguy
Copy link
Collaborator Author

I can close the socket in the unit test underneath the connection since I'm in the same file. But this only simulates the other end closing. It will verify the logic I'm going to add is sound, but what I don't know is whether the Phobos socket type will register a close when the server closes it, as I don't know how that works. Typical blocking sockets don't tell you they are closed until you try to read from them. I think vibe.d sockets are going to proactively mark the socket closed when that event shows up (which is why I can check it inside autoPurge).

It may be more robust to simply check the exception and if the socket is now closed, just ignore the exception during auto-purge.

@schveiguy
Copy link
Collaborator Author

@Abscissa OK, so I'm ready to make a PR. However, I don't want to use the master branch, because you are working on 2.0.0. I was hoping to just get a 1.2.2 version. Can you make a branch for this?

schveiguy added a commit to schveiguy/mysql-native that referenced this issue Jan 26, 2018
terminated the connection. In general resetting the connection now
resets all pending states that are moot.
@schveiguy
Copy link
Collaborator Author

In terms of testing, what do I need set up in my environment to to run dub test on the library? I don't want to demolish my existing mysql server ;)

schveiguy added a commit to schveiguy/mysql-native that referenced this issue Jan 26, 2018
terminated the connection. In general resetting the connection now
resets all pending states that are moot.
schveiguy added a commit to schveiguy/mysql-native that referenced this issue Jan 26, 2018
terminated the connection. In general resetting the connection now
resets all pending states that are moot.
@Abscissa
Copy link

Abscissa commented Jan 26, 2018 via email

@Abscissa
Copy link

Abscissa commented Jan 26, 2018 via email

@Abscissa
Copy link

Ok, I've created branch "v1.2.x", based on the tagged "v1.2.1"

schveiguy added a commit to schveiguy/mysql-native that referenced this issue Jan 27, 2018
terminated the connection. In general resetting the connection now
resets all pending states that are moot.
@schveiguy
Copy link
Collaborator Author

PR: #155

Abscissa pushed a commit that referenced this issue Jan 27, 2018
…unusable (#155)

* Added unittest for 154

* Fix #154 - autoPurge does not handle cases where the server has
terminated the connection. In general resetting the connection now
resets all pending states that are moot.
@schveiguy
Copy link
Collaborator Author

Not sure why this didn't auto-close, I thought it would with the commit message.

Abscissa added a commit to Abscissa/mysql-native that referenced this issue Feb 4, 2018
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

2 participants