-
-
Notifications
You must be signed in to change notification settings - Fork 85
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
preventing CancelledKeyException #170
Conversation
My suggested behavior in #168 was to trigger a pseudo-read interest, so that when this monitor selects for reading and a read is attempted, Perhaps a good first step is to confirm this is what the libev backend does already. The easiest way to do that is probably to write a test, and make sure the behavior is consistent across both backends. |
Easy if it were deterministic :) During my tries, I even found out a I can tell you that, by having just a quick look at the SelectionKey and Selector APIs, that a few of the methods used in the extension are not being guarded against, such as:
A combination of factors can make these exceptions potentially leak to nio, i.e. the selector loops in one thread and is closed in a different one. I'll see about reproducing this, but it could be a good idea just to rescue these exceptions and act accordingly (even if not in the way I did). |
I was suggesting writing tests for the libev backend in this case, then making the Java implementation match the libev behavior (or choose a meet-in-the-middle behavior). My assumption is under the libev backend objects will select readable if closed, so that an attempted read operation will raise It would be good to confirm that is actually the case. |
Ahh, I see your point now. I'll see about doing that. Still, all of those other exceptions should be taken into consideration, as they aren't handled anywhere. |
Handling them will require ensuring consistent semantics with the libev-backend, even if it involves having them pseudo-select as readable when the exception is thrown. |
I added a test to show the inconsistency in an edge case of the libev/nio backends, namely after the selectable has been closed, the readiness changes to This is because of the I didn't managed to trigger the aforementioned Exception yet, but based on this result, I'd say that this is a fundamental difference between the two implementations. |
This thread also explain well what's going on. Specifically, if the key is being selected in a separate thread and handled/closed somewhere else, it might lead to the CancelledKeyException. |
I also have another test here, and when I comment this line here, I can reproduce it more deterministically. What I see is that the keys are only cancelled before the |
One way or another the behavior should be made consistent. What I have been vaguely suggesting above is catching the This may or may not involve some active tracking of a closed state in the monitor object. If the current libev backend behavior doesn't make sense, it may need a (breaking) change. |
@tarcieri I really think that a better approach would be to use the #isValid API everywhere before a method call that might blow. This is the recommended solution in the links I posted, there are just too many places this can happen (list of NIO4r methods above) and I don't think that the lib will benefit from forcing parity in this case. I also suspect that this issue never arose before because most |
the last commit shows the minimal set of changes needed to be done to: make my test pass, and prevent the exception for the particular case I'm using it in (when calling I think that more work could be done to prevent similar exceptions with other java NIO used API (i.e.: |
38e8600
to
175dcc1
Compare
and travis is breaking due to not being able to resolve localhost (?). Related to #172 |
@HoneyryderChuck try rebasing. #172 is fixed now |
…r selects an already closed key
175dcc1
to
01ab970
Compare
@tarcieri done |
This looks good as a baseline fix |
Fixes #168 .
I'm not sure about what to do when the failure happens though, as right now I'm just ignoring it.
@tarcieri could use some suggestion here.
Due to the non-deterministic nature of it, can't also come up with a proper unit test.