|
39 | 39 | import io.netty.channel.ChannelFuture;
|
40 | 40 | import io.netty.channel.ChannelPromise;
|
41 | 41 | import java.net.InetSocketAddress;
|
| 42 | +import java.util.ArrayList; |
42 | 43 | import java.util.Collections;
|
| 44 | +import java.util.List; |
43 | 45 | import java.util.concurrent.TimeUnit;
|
44 | 46 | import org.junit.Before;
|
45 | 47 | import org.junit.Test;
|
@@ -256,7 +258,7 @@ public void should_refuse_new_writes_during_graceful_close() {
|
256 | 258 | }
|
257 | 259 |
|
258 | 260 | @Test
|
259 |
| - public void should_close_gracefully_if_orphan_ids_above_max_and_pending_requests() { |
| 261 | + public void should_close_gracefully_if_orphan_ids_above_max_and_pending_request() { |
260 | 262 | // Given
|
261 | 263 | addToPipeline();
|
262 | 264 | // Generate n orphan ids by writing and cancelling the requests:
|
@@ -311,6 +313,65 @@ public void should_close_gracefully_if_orphan_ids_above_max_and_pending_requests
|
311 | 313 | assertThat(channel.closeFuture()).isSuccess();
|
312 | 314 | }
|
313 | 315 |
|
| 316 | + @Test |
| 317 | + public void should_close_gracefully_if_orphan_ids_above_max_and_multiple_pending_requests() { |
| 318 | + // Given |
| 319 | + addToPipeline(); |
| 320 | + // Generate n orphan ids by writing and cancelling the requests. |
| 321 | + for (int i = 0; i < MAX_ORPHAN_IDS; i++) { |
| 322 | + when(streamIds.acquire()).thenReturn(i); |
| 323 | + MockResponseCallback responseCallback = new MockResponseCallback(); |
| 324 | + channel |
| 325 | + .writeAndFlush( |
| 326 | + new DriverChannel.RequestMessage(QUERY, false, Frame.NO_PAYLOAD, responseCallback)) |
| 327 | + .awaitUninterruptibly(); |
| 328 | + channel.writeAndFlush(responseCallback).awaitUninterruptibly(); |
| 329 | + } |
| 330 | + // Generate 3 additional requests that are pending and not cancelled. |
| 331 | + List<MockResponseCallback> pendingResponseCallbacks = new ArrayList<>(); |
| 332 | + for (int i = 0; i < 3; i++) { |
| 333 | + when(streamIds.acquire()).thenReturn(MAX_ORPHAN_IDS + i); |
| 334 | + MockResponseCallback responseCallback = new MockResponseCallback(); |
| 335 | + channel |
| 336 | + .writeAndFlush( |
| 337 | + new DriverChannel.RequestMessage(QUERY, false, Frame.NO_PAYLOAD, responseCallback)) |
| 338 | + .awaitUninterruptibly(); |
| 339 | + pendingResponseCallbacks.add(responseCallback); |
| 340 | + } |
| 341 | + |
| 342 | + // When |
| 343 | + // Generate the n+1th orphan id that makes us go above the threshold by canceling one if the |
| 344 | + // pending requests. |
| 345 | + channel.writeAndFlush(pendingResponseCallbacks.remove(0)).awaitUninterruptibly(); |
| 346 | + |
| 347 | + // Then |
| 348 | + // Channel should be closing gracefully but there's no way to observe that from the outside |
| 349 | + // besides writing another request and check that it's rejected. |
| 350 | + assertThat(channel.closeFuture()).isNotDone(); |
| 351 | + ChannelFuture otherWriteFuture = |
| 352 | + channel.writeAndFlush( |
| 353 | + new DriverChannel.RequestMessage( |
| 354 | + QUERY, false, Frame.NO_PAYLOAD, new MockResponseCallback())); |
| 355 | + assertThat(otherWriteFuture).isFailed(); |
| 356 | + assertThat(otherWriteFuture.cause()) |
| 357 | + .isInstanceOf(IllegalStateException.class) |
| 358 | + .hasMessage("Channel is closing"); |
| 359 | + |
| 360 | + // When |
| 361 | + // Cancel the remaining pending requests causing the n+ith orphan ids above the threshold. |
| 362 | + for (MockResponseCallback pendingResponseCallback : pendingResponseCallbacks) { |
| 363 | + ChannelFuture future = channel.writeAndFlush(pendingResponseCallback).awaitUninterruptibly(); |
| 364 | + |
| 365 | + // Then |
| 366 | + // The future should succeed even though the channel has started closing gracefully. |
| 367 | + assertThat(future).isSuccess(); |
| 368 | + } |
| 369 | + |
| 370 | + // Then |
| 371 | + // The graceful shutdown completes. |
| 372 | + assertThat(channel.closeFuture()).isSuccess(); |
| 373 | + } |
| 374 | + |
314 | 375 | @Test
|
315 | 376 | public void should_close_immediately_if_orphan_ids_above_max_and_no_pending_requests() {
|
316 | 377 | // Given
|
|
0 commit comments