-
Notifications
You must be signed in to change notification settings - Fork 1.6k
NettyResponseFuture never completes because netty provider uses closed channel #415
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
Comments
good analysis, in my test, I have thread pool and latch in my stress client side, callback will simply do latch.countDown(), and I constantly see my threads stuck, meaning some callbacks never being called. Wondering how this basic is missed. |
Once again, please share your test case, as you claim to have one where you can easily reproduce. |
@slandelle, are you asking for a test case to reproduce a race condition? Have you read the analysis, what do you think about it? |
@hvesalai What a mess! Thanks for your analysis. I'm afraid I'll only be able to come up with an ugly fix for AHC 1. Will try to come up with something better for AHC 2. |
I've just pushed an imperfect fix on 1.7.X branch. Limitations are:
Will first port the logic as is on AHC2, but we'll try to come up with something better (maybe use Netty custom events). |
Still not perfect, but chances are much much slower now (just a few simple instructions) |
Using version 1.7.21, a NettyResponseFuture never gets completed because the provider uses a channel that has already been closed and handled by
closeChannel(...)
.If I have read the source properly, what we have here is a classical race condition:
[in client thread]
doConnect(...)
is called and a cached channel is selected.At this point, the attachment connected to the channel is still
DiscardEvent
NettyAsyncHttpProvider.java#L913
doConnect(...)
checks that the connection isOpen(), which it still is.NettyAsyncHttpProvider.java#L923
[in I/O thread] The channel is closed by the remote end and
channelClosed(...)
is called. Since the attachment isDiscardEvent
, nothing is done.NettyAsyncHttpProvider.java#L1341
[in client thread]
doConnect(...)
continues using the now closed channel by attaching aNettyResponseFuture
to the channel.NettyAsyncHttpProvider.java#L937
[in client thread]
doConnect(...)
callswriteRequest(...)
which checks if the channel is closed, which it is.NettyAsyncHttpProvider.java#L447
However,
writeRequest(...)
does nothing about the fact, relying onchannelClosed(...)
to handle the situation. But, aschannelClosed(...)
has already been executed at step 2, theabort(...)
ordone(...)
methods will never get called, resulting in that the listeners of the future will never get notified.The text was updated successfully, but these errors were encountered: