Skip to content

Commit 0d6af34

Browse files
committed
Replace dynamic proxy used for queue-slot release with explicit handler wrapper.
1 parent ea8d09f commit 0d6af34

File tree

7 files changed

+306
-90
lines changed

7 files changed

+306
-90
lines changed

httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncClientExchangeHandlerProxy.java

Lines changed: 0 additions & 86 deletions
This file was deleted.

httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ public final H2AsyncClientBuilder disableRequestPriority() {
334334
*
335335
* @param max maximum number of queued requests; {@code <= 0} to disable the cap
336336
* @return this builder
337-
* @since 5.6
337+
* @since 5.7
338338
*/
339339
@Experimental
340340
public final H2AsyncClientBuilder setMaxQueuedRequests(final int max) {

httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ public HttpAsyncClientBuilder disableContentCompression() {
909909
*
910910
* @param max maximum number of queued requests; <= 0 to disable the cap
911911
* @return this builder
912-
* @since 5.6
912+
* @since 5.7
913913
*/
914914
@Experimental
915915
public HttpAsyncClientBuilder setMaxQueuedRequests(final int max) {

httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalH2AsyncExecRuntime.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ public Cancellable execute(
293293
return Operations.nonCancellable();
294294
}
295295
final AsyncClientExchangeHandler actual = sharedQueued != null
296-
? AsyncClientExchangeHandlerProxy.newProxy(exchangeHandler, this::releaseSlot)
296+
? new ReleasingAsyncClientExchangeHandler(exchangeHandler, this::releaseSlot)
297297
: exchangeHandler;
298298
final ComplexCancellable complexCancellable = new ComplexCancellable();
299299
final IOSession session = endpoint.session;

httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ private AsyncClientExchangeHandler guard(final AsyncClientExchangeHandler handle
324324
if (sharedQueued == null) {
325325
return handler;
326326
}
327-
return AsyncClientExchangeHandlerProxy.newProxy(handler, this::releaseSlot);
327+
return new ReleasingAsyncClientExchangeHandler(handler, this::releaseSlot);
328328
}
329329

330330
@Override
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* ====================================================================
3+
* Licensed to the Apache Software Foundation (ASF) under one
4+
* or more contributor license agreements. See the NOTICE file
5+
* distributed with this work for additional information
6+
* regarding copyright ownership. The ASF licenses this file
7+
* to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance
9+
* with the License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing,
14+
* software distributed under the License is distributed on an
15+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
* KIND, either express or implied. See the License for the
17+
* specific language governing permissions and limitations
18+
* under the License.
19+
* ====================================================================
20+
*
21+
* This software consists of voluntary contributions made by many
22+
* individuals on behalf of the Apache Software Foundation. For more
23+
* information on the Apache Software Foundation, please see
24+
* <http://www.apache.org/>.
25+
*
26+
*/
27+
package org.apache.hc.client5.http.impl.async;
28+
29+
import java.io.IOException;
30+
import java.nio.ByteBuffer;
31+
import java.util.List;
32+
import java.util.concurrent.atomic.AtomicBoolean;
33+
34+
import org.apache.hc.core5.annotation.Internal;
35+
import org.apache.hc.core5.http.EntityDetails;
36+
import org.apache.hc.core5.http.Header;
37+
import org.apache.hc.core5.http.HttpException;
38+
import org.apache.hc.core5.http.HttpResponse;
39+
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
40+
import org.apache.hc.core5.http.nio.CapacityChannel;
41+
import org.apache.hc.core5.http.nio.DataStreamChannel;
42+
import org.apache.hc.core5.http.nio.RequestChannel;
43+
import org.apache.hc.core5.http.protocol.HttpContext;
44+
45+
@Internal
46+
final class ReleasingAsyncClientExchangeHandler implements AsyncClientExchangeHandler {
47+
48+
private final AsyncClientExchangeHandler handler;
49+
private final Runnable onRelease;
50+
private final AtomicBoolean released;
51+
52+
ReleasingAsyncClientExchangeHandler(final AsyncClientExchangeHandler handler, final Runnable onRelease) {
53+
this.handler = handler;
54+
this.onRelease = onRelease;
55+
this.released = new AtomicBoolean(false);
56+
}
57+
58+
@Override
59+
public void produceRequest(final RequestChannel channel, final HttpContext context) throws HttpException, IOException {
60+
handler.produceRequest(channel, context);
61+
}
62+
63+
@Override
64+
public void consumeResponse(final HttpResponse response, final EntityDetails entityDetails, final HttpContext context)
65+
throws HttpException, IOException {
66+
handler.consumeResponse(response, entityDetails, context);
67+
}
68+
69+
@Override
70+
public void consumeInformation(final HttpResponse response, final HttpContext context) throws HttpException, IOException {
71+
handler.consumeInformation(response, context);
72+
}
73+
74+
@Override
75+
public int available() {
76+
return handler.available();
77+
}
78+
79+
@Override
80+
public void produce(final DataStreamChannel channel) throws IOException {
81+
handler.produce(channel);
82+
}
83+
84+
@Override
85+
public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
86+
handler.updateCapacity(capacityChannel);
87+
}
88+
89+
@Override
90+
public void consume(final ByteBuffer src) throws IOException {
91+
handler.consume(src);
92+
}
93+
94+
@Override
95+
public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
96+
handler.streamEnd(trailers);
97+
}
98+
99+
@Override
100+
public void failed(final Exception cause) {
101+
handler.failed(cause);
102+
}
103+
104+
@Override
105+
public void cancel() {
106+
handler.cancel();
107+
}
108+
109+
@Override
110+
public void releaseResources() {
111+
try {
112+
handler.releaseResources();
113+
} finally {
114+
if (released.compareAndSet(false, true)) {
115+
try {
116+
onRelease.run();
117+
} catch (final RuntimeException ignore) {
118+
}
119+
}
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)