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:
parent
f6251c8256
commit
b0823761f4
@ -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;
|
||||
}
|
||||
|
@ -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>());
|
||||
|
Loading…
Reference in New Issue
Block a user