13
13
*/
14
14
package org .asynchttpclient .netty .channel ;
15
15
16
- import static org .asynchttpclient .util .MiscUtils .trimStackTrace ;
17
16
import io .netty .bootstrap .Bootstrap ;
18
17
import io .netty .bootstrap .ChannelFactory ;
19
18
import io .netty .buffer .ByteBufAllocator ;
35
34
import io .netty .handler .logging .LoggingHandler ;
36
35
import io .netty .handler .ssl .SslHandler ;
37
36
import io .netty .handler .stream .ChunkedWriteHandler ;
38
- import io .netty .util .AttributeKey ;
39
37
import io .netty .util .Timer ;
40
38
import io .netty .util .concurrent .DefaultThreadFactory ;
41
39
import io .netty .util .concurrent .GlobalEventExecutor ;
42
40
43
- import java .io .IOException ;
44
41
import java .util .Map .Entry ;
45
- import java .util .concurrent .ConcurrentHashMap ;
46
42
import java .util .concurrent .ThreadFactory ;
47
43
import java .util .concurrent .TimeUnit ;
48
44
55
51
import org .asynchttpclient .channel .ChannelPool ;
56
52
import org .asynchttpclient .channel .ChannelPoolPartitioning ;
57
53
import org .asynchttpclient .channel .NoopChannelPool ;
58
- import org .asynchttpclient .exception .PoolAlreadyClosedException ;
59
- import org .asynchttpclient .exception .TooManyConnectionsException ;
60
- import org .asynchttpclient .exception .TooManyConnectionsPerHostException ;
61
54
import org .asynchttpclient .handler .AsyncHandlerExtensions ;
62
55
import org .asynchttpclient .netty .OnLastHttpContentCallback ;
63
56
import org .asynchttpclient .netty .NettyResponseFuture ;
@@ -87,30 +80,23 @@ public class ChannelManager {
87
80
public static final String AHC_WS_HANDLER = "ahc-ws" ;
88
81
public static final String LOGGING_HANDLER = "logging" ;
89
82
90
- private static final AttributeKey <Object > partitionKeyAttr = AttributeKey .valueOf ("partitionKey" );
91
-
92
83
private final AsyncHttpClientConfig config ;
93
84
private final SslEngineFactory sslEngineFactory ;
94
85
private final EventLoopGroup eventLoopGroup ;
95
86
private final boolean allowReleaseEventLoopGroup ;
96
87
private final Bootstrap httpBootstrap ;
97
88
private final Bootstrap wsBootstrap ;
98
89
private final long handshakeTimeout ;
99
- private final IOException tooManyConnections ;
100
- private final IOException tooManyConnectionsPerHost ;
101
90
102
91
private final ChannelPool channelPool ;
103
92
private final ChannelGroup openChannels ;
104
- private final boolean maxTotalConnectionsEnabled ;
105
- private final NonBlockingSemaphoreLike freeChannels ;
106
- private final boolean maxConnectionsPerHostEnabled ;
107
- private final ConcurrentHashMap <Object , NonBlockingSemaphore > freeChannelsPerHost = new ConcurrentHashMap <>();
108
93
109
94
private AsyncHttpClientHandler wsHandler ;
110
95
111
96
public ChannelManager (final AsyncHttpClientConfig config , Timer nettyTimer ) {
112
97
113
98
this .config = config ;
99
+
114
100
this .sslEngineFactory = config .getSslEngineFactory () != null ? config .getSslEngineFactory () : new DefaultSslEngineFactory ();
115
101
try {
116
102
this .sslEngineFactory .init (config );
@@ -128,37 +114,7 @@ public ChannelManager(final AsyncHttpClientConfig config, Timer nettyTimer) {
128
114
}
129
115
this .channelPool = channelPool ;
130
116
131
- tooManyConnections = trimStackTrace (new TooManyConnectionsException (config .getMaxConnections ()));
132
- tooManyConnectionsPerHost = trimStackTrace (new TooManyConnectionsPerHostException (config .getMaxConnectionsPerHost ()));
133
- maxTotalConnectionsEnabled = config .getMaxConnections () > 0 ;
134
- maxConnectionsPerHostEnabled = config .getMaxConnectionsPerHost () > 0 ;
135
-
136
- freeChannels = maxTotalConnectionsEnabled ?
137
- new NonBlockingSemaphore (config .getMaxConnections ()) :
138
- NonBlockingSemaphoreInfinite .INSTANCE ;
139
-
140
- if (maxTotalConnectionsEnabled || maxConnectionsPerHostEnabled ) {
141
- openChannels = new DefaultChannelGroup ("asyncHttpClient" , GlobalEventExecutor .INSTANCE ) {
142
- @ Override
143
- public boolean remove (Object o ) {
144
- boolean removed = super .remove (o );
145
- if (removed ) {
146
- freeChannels .release ();
147
- if (maxConnectionsPerHostEnabled ) {
148
- Object partitionKey = Channel .class .cast (o ).attr (partitionKeyAttr ).getAndSet (null );
149
- if (partitionKey != null ) {
150
- NonBlockingSemaphore hostFreeChannels = freeChannelsPerHost .get (partitionKey );
151
- if (hostFreeChannels != null )
152
- hostFreeChannels .release ();
153
- }
154
- }
155
- }
156
- return removed ;
157
- }
158
- };
159
- } else {
160
- openChannels = new DefaultChannelGroup ("asyncHttpClient" , GlobalEventExecutor .INSTANCE );
161
- }
117
+ openChannels = new DefaultChannelGroup ("asyncHttpClient" , GlobalEventExecutor .INSTANCE );
162
118
163
119
handshakeTimeout = config .getHandshakeTimeout ();
164
120
@@ -308,10 +264,7 @@ public final void tryToOfferChannelToPool(Channel channel, AsyncHandler<?> async
308
264
Channels .setDiscard (channel );
309
265
if (asyncHandler instanceof AsyncHandlerExtensions )
310
266
AsyncHandlerExtensions .class .cast (asyncHandler ).onConnectionOffer (channel );
311
- if (channelPool .offer (channel , partitionKey )) {
312
- if (maxConnectionsPerHostEnabled )
313
- channel .attr (partitionKeyAttr ).setIfAbsent (partitionKey );
314
- } else {
267
+ if (!channelPool .offer (channel , partitionKey )) {
315
268
// rejected by pool
316
269
closeChannel (channel );
317
270
}
@@ -330,32 +283,6 @@ public boolean removeAll(Channel connection) {
330
283
return channelPool .removeAll (connection );
331
284
}
332
285
333
- private boolean tryAcquireGlobal () {
334
- return freeChannels .tryAcquire ();
335
- }
336
-
337
- private NonBlockingSemaphoreLike getFreeConnectionsForHost (Object partitionKey ) {
338
- return maxConnectionsPerHostEnabled ?
339
- freeChannelsPerHost .computeIfAbsent (partitionKey , pk -> new NonBlockingSemaphore (config .getMaxConnectionsPerHost ())) :
340
- NonBlockingSemaphoreInfinite .INSTANCE ;
341
- }
342
-
343
- private boolean tryAcquirePerHost (Object partitionKey ) {
344
- return getFreeConnectionsForHost (partitionKey ).tryAcquire ();
345
- }
346
-
347
- public void acquireChannelLock (Object partitionKey ) throws IOException {
348
- if (!channelPool .isOpen ())
349
- throw PoolAlreadyClosedException .INSTANCE ;
350
- if (!tryAcquireGlobal ())
351
- throw tooManyConnections ;
352
- if (!tryAcquirePerHost (partitionKey )) {
353
- freeChannels .release ();
354
-
355
- throw tooManyConnectionsPerHost ;
356
- }
357
- }
358
-
359
286
private void doClose () {
360
287
openChannels .close ();
361
288
channelPool .destroy ();
@@ -376,16 +303,8 @@ public void closeChannel(Channel channel) {
376
303
Channels .silentlyCloseChannel (channel );
377
304
}
378
305
379
- public void releaseChannelLock (Object partitionKey ) {
380
- freeChannels .release ();
381
- getFreeConnectionsForHost (partitionKey ).release ();
382
- }
383
-
384
306
public void registerOpenChannel (Channel channel , Object partitionKey ) {
385
307
openChannels .add (channel );
386
- if (maxConnectionsPerHostEnabled ) {
387
- channel .attr (partitionKeyAttr ).set (partitionKey );
388
- }
389
308
}
390
309
391
310
private HttpClientCodec newHttpClientCodec () {
@@ -489,4 +408,8 @@ public ChannelPool getChannelPool() {
489
408
public EventLoopGroup getEventLoopGroup () {
490
409
return eventLoopGroup ;
491
410
}
411
+
412
+ public boolean isOpen () {
413
+ return channelPool .isOpen ();
414
+ }
492
415
}
0 commit comments