Skip to content

Netty ChannelManager.tryToOfferChannelToPool discard chunks after offering to pool #834

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

Closed
maxpower-artvandelay opened this issue Mar 6, 2015 · 2 comments
Assignees
Milestone

Comments

@maxpower-artvandelay
Copy link
Contributor

Hello, the Netty ChannelManager(AHC 1.9.11) seems to have an issue on tryToOfferChannelToPool.

public final void tryToOfferChannelToPool(Channel channel, boolean keepAlive, String partition) {
    if (channel.isConnected() && keepAlive && channel.isReadable()) {
        LOGGER.debug("Adding key: {} for channel {}", partition, channel);
        channelPool.offer(channel, partition);
        if (maxConnectionsPerHostEnabled)
            channelId2KeyPool.putIfAbsent(channel.getId(), partition);
        Channels.setDiscard(channel);
    } else {
        // not offered
        closeChannel(channel);
    }
}

Looks like channelPool.offer should happen after Channels.setDiscard, otherwise the channel becomes available for selection while the previous request cleanup is still happening. This will cause a "java.util.concurrent.TimeoutException: Request timed out" under certain loads.

This is the snippet I used to reproduce the issue:

final AsyncCompletionHandler<Response> handler = new AsyncCompletionHandler<Response>() {
    @Override
    public void onThrowable(Throwable t) {
        System.out.println(t.toString());
    }

    @Override
    public Response onCompleted(Response response) throws Exception {
        return response;
    }
};

Request request = httpClient.prepareGet("http://.../").build();
for (int i = 0; i < 500; ++i) {
    httpClient.executeRequest(request, handler);
}

I think the fix should be something similar to:

Channels.setDiscard(channel);
channelPool.offer(channel, partition);

instead of :

channelPool.offer(channel, partition);
Channels.setDiscard(channel);
maxpower-artvandelay added a commit to maxpower-artvandelay/async-http-client that referenced this issue Mar 6, 2015
@slandelle slandelle added this to the 1.9.12 milestone Mar 8, 2015
@slandelle slandelle self-assigned this Mar 8, 2015
@slandelle slandelle changed the title Netty ChannelManager.tryToOfferChannelToPool makes channel available for selection prematurely Netty ChannelManager.tryToOfferChannelToPool discard chunks after offering to pool Mar 8, 2015
@slandelle
Copy link
Contributor

More exactly: tryToOfferChannelToPool sets channel flag to discard after offering, but channel could possibly have been selected in the meanwhile.

@slandelle
Copy link
Contributor

@maxpower-artvandelay Nice catch, thanks for fixing!

slandelle added a commit that referenced this issue Mar 8, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants