PendingWriteQueue to handle write operations with void future

Motivation:

Right now PendingWriteQueue.removeAndWriteAll collects all promises to
PromiseCombiner instance which sets listener to each given promise throwing
IllegalStateException on VoidChannelPromise which breaks while loop
and "reports" operation as failed (when in fact part of writes might be
actually written).

Modifications:

Check if the promise is not void before adding it to the PromiseCombiner
instance.

Result:

PendingWriteQueue.removeAndWriteAll succesfully writes all pendings
even in case void promise was used.
This commit is contained in:
Alexey Kachayev 2018-03-14 20:08:24 +02:00 committed by Norman Maurer
parent f6251c8256
commit b0823761f4
2 changed files with 27 additions and 1 deletions

View File

@ -144,7 +144,9 @@ public final class PendingWriteQueue {
Object msg = write.msg;
ChannelPromise promise = write.promise;
recycle(write, false);
combiner.add(promise);
if (!(promise instanceof VoidChannelPromise)) {
combiner.add(promise);
}
ctx.write(msg, promise);
write = next;
}

View File

@ -264,6 +264,30 @@ public class PendingWriteQueueTest {
assertEquals(3L, channel.readOutbound());
}
@Test
public void testRemoveAndWriteAllWithVoidPromise() {
EmbeddedChannel channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter() {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
// Convert to writeAndFlush(...) so the promise will be notified by the transport.
ctx.writeAndFlush(msg, promise);
}
}, new ChannelOutboundHandlerAdapter());
final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().lastContext());
ChannelPromise promise = channel.newPromise();
queue.add(1L, promise);
queue.add(2L, channel.voidPromise());
queue.removeAndWriteAll();
assertTrue(channel.finish());
assertTrue(promise.isDone());
assertTrue(promise.isSuccess());
assertEquals(1L, channel.readOutbound());
assertEquals(2L, channel.readOutbound());
}
@Test
public void testRemoveAndFailAllReentrantWrite() {
final List<Integer> failOrder = Collections.synchronizedList(new ArrayList<Integer>());