Retain ByteBuf extras when aggregating
Motivation: BinaryMemcacheObjectAggregator doesn't retain ByteBuf `extras`. So `io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1` will be thrown when aggregating a message containing `extras`. See the unit test for an example. Modifications: `ratain` extras to fix IllegalReferenceCountException. Result: `extras` is retained.
This commit is contained in:
parent
11bcb8790c
commit
501c35afff
@ -53,8 +53,9 @@ public class BinaryMemcacheObjectAggregator extends AbstractMemcacheObjectAggreg
|
||||
}
|
||||
|
||||
private static FullBinaryMemcacheRequest toFullRequest(BinaryMemcacheRequest request, ByteBuf content) {
|
||||
ByteBuf extras = request.extras() == null ? null : request.extras().retain();
|
||||
FullBinaryMemcacheRequest fullRequest =
|
||||
new DefaultFullBinaryMemcacheRequest(request.key(), request.extras(), content);
|
||||
new DefaultFullBinaryMemcacheRequest(request.key(), extras, content);
|
||||
|
||||
fullRequest.setMagic(request.magic());
|
||||
fullRequest.setOpcode(request.opcode());
|
||||
@ -70,8 +71,9 @@ public class BinaryMemcacheObjectAggregator extends AbstractMemcacheObjectAggreg
|
||||
}
|
||||
|
||||
private static FullBinaryMemcacheResponse toFullResponse(BinaryMemcacheResponse response, ByteBuf content) {
|
||||
ByteBuf extras = response.extras() == null ? null : response.extras().retain();
|
||||
FullBinaryMemcacheResponse fullResponse =
|
||||
new DefaultFullBinaryMemcacheResponse(response.key(), response.extras(), content);
|
||||
new DefaultFullBinaryMemcacheResponse(response.key(), extras, content);
|
||||
|
||||
fullResponse.setMagic(response.magic());
|
||||
fullResponse.setOpcode(response.opcode());
|
||||
|
@ -18,12 +18,17 @@ package io.netty.handler.codec.memcache.binary;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import io.netty.handler.codec.memcache.DefaultLastMemcacheContent;
|
||||
import io.netty.handler.codec.memcache.DefaultMemcacheContent;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.core.IsNull.notNullValue;
|
||||
import static org.hamcrest.core.IsNull.nullValue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Verifies the correct functionality of the {@link BinaryMemcacheObjectAggregator}.
|
||||
@ -73,4 +78,40 @@ public class BinaryMemcacheObjectAggregatorTest {
|
||||
|
||||
channel.finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRetainByteBufWhenAggregating() {
|
||||
channel = new EmbeddedChannel(
|
||||
new BinaryMemcacheRequestEncoder(),
|
||||
new BinaryMemcacheRequestDecoder(),
|
||||
new BinaryMemcacheObjectAggregator(MAX_CONTENT_SIZE));
|
||||
|
||||
String key = "Netty";
|
||||
ByteBuf extras = Unpooled.copiedBuffer("extras", CharsetUtil.UTF_8);
|
||||
BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(key, extras);
|
||||
request.setKeyLength((short) key.length());
|
||||
request.setExtrasLength((byte) extras.readableBytes());
|
||||
|
||||
DefaultMemcacheContent content1 =
|
||||
new DefaultMemcacheContent(Unpooled.copiedBuffer("Netty", CharsetUtil.UTF_8));
|
||||
DefaultLastMemcacheContent content2 =
|
||||
new DefaultLastMemcacheContent(Unpooled.copiedBuffer(" Rocks!", CharsetUtil.UTF_8));
|
||||
int totalBodyLength = key.length() + extras.readableBytes() +
|
||||
content1.content().readableBytes() + content2.content().readableBytes();
|
||||
request.setTotalBodyLength(totalBodyLength);
|
||||
|
||||
assertTrue(channel.writeOutbound(request, content1, content2));
|
||||
|
||||
assertThat(channel.outboundMessages().size(), is(3));
|
||||
assertTrue(channel.writeInbound(channel.readOutbound(), channel.readOutbound(), channel.readOutbound()));
|
||||
|
||||
FullBinaryMemcacheRequest read = channel.readInbound();
|
||||
assertThat(read, notNullValue());
|
||||
assertThat(read.key(), is("Netty"));
|
||||
assertThat(read.extras().toString(CharsetUtil.UTF_8), is("extras"));
|
||||
assertThat(read.content().toString(CharsetUtil.UTF_8), is("Netty Rocks!"));
|
||||
|
||||
read.release();
|
||||
assertFalse(channel.finish());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user