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) {
|
private static FullBinaryMemcacheRequest toFullRequest(BinaryMemcacheRequest request, ByteBuf content) {
|
||||||
|
ByteBuf extras = request.extras() == null ? null : request.extras().retain();
|
||||||
FullBinaryMemcacheRequest fullRequest =
|
FullBinaryMemcacheRequest fullRequest =
|
||||||
new DefaultFullBinaryMemcacheRequest(request.key(), request.extras(), content);
|
new DefaultFullBinaryMemcacheRequest(request.key(), extras, content);
|
||||||
|
|
||||||
fullRequest.setMagic(request.magic());
|
fullRequest.setMagic(request.magic());
|
||||||
fullRequest.setOpcode(request.opcode());
|
fullRequest.setOpcode(request.opcode());
|
||||||
@ -70,8 +71,9 @@ public class BinaryMemcacheObjectAggregator extends AbstractMemcacheObjectAggreg
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static FullBinaryMemcacheResponse toFullResponse(BinaryMemcacheResponse response, ByteBuf content) {
|
private static FullBinaryMemcacheResponse toFullResponse(BinaryMemcacheResponse response, ByteBuf content) {
|
||||||
|
ByteBuf extras = response.extras() == null ? null : response.extras().retain();
|
||||||
FullBinaryMemcacheResponse fullResponse =
|
FullBinaryMemcacheResponse fullResponse =
|
||||||
new DefaultFullBinaryMemcacheResponse(response.key(), response.extras(), content);
|
new DefaultFullBinaryMemcacheResponse(response.key(), extras, content);
|
||||||
|
|
||||||
fullResponse.setMagic(response.magic());
|
fullResponse.setMagic(response.magic());
|
||||||
fullResponse.setOpcode(response.opcode());
|
fullResponse.setOpcode(response.opcode());
|
||||||
|
@ -18,12 +18,17 @@ package io.netty.handler.codec.memcache.binary;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
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 org.junit.Test;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.hamcrest.MatcherAssert.*;
|
import static org.hamcrest.MatcherAssert.*;
|
||||||
import static org.hamcrest.core.IsNull.notNullValue;
|
import static org.hamcrest.core.IsNull.notNullValue;
|
||||||
import static org.hamcrest.core.IsNull.nullValue;
|
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}.
|
* Verifies the correct functionality of the {@link BinaryMemcacheObjectAggregator}.
|
||||||
@ -73,4 +78,40 @@ public class BinaryMemcacheObjectAggregatorTest {
|
|||||||
|
|
||||||
channel.finish();
|
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