Class PooledObjects
Bytes
and manage its life cycle.
Warning: Using a pooled Bytes
is very advanced and can open up much more complicated
management of a reference counted Bytes
. You should only ever do this if you are very comfortable
with Netty. It is recommended to also read through
Reference counted objects
for more information on pooled objects.
What is a pooled Bytes
?
A pooled Bytes
is a special variant of Bytes
whose Bytes.isPooled()
returns true
. Currently, HttpData
is a Bytes
and it's usually created via
HttpData.wrap(ByteBuf)
by wrapping an existing ByteBuf
.
It can appear when you consume data using the operations such as:
StreamMessage.subscribe(Subscriber, SubscriptionOption...)
withSubscriptionOption.WITH_POOLED_OBJECTS
HttpRequest.aggregate(AggregationOptions)
withAggregationOptions.usePooledObjects(ByteBufAllocator)
HttpResponse.aggregate(AggregationOptions)
withAggregationOptions.usePooledObjects(ByteBufAllocator)
HttpFile.aggregateWithPooledObjects(Executor, ByteBufAllocator)
To put it another way, you'll never see a pooled Bytes
if you did not use such
operations. You can ignore the rest of this section if that's the case.
Any time you receive a pooled Bytes
, it will have an underlying ByteBuf
that must be
released - failure to release the ByteBuf
will result in a memory leak and poor performance.
You must make sure to do this by calling Bytes.close()
, usually in a try-with-resources structure
to avoid side effects, e.g.
HttpResponse res = client.get("/");
res.aggregate(AggregationOptions.usePooledObjects(ctx.alloc(), ctx.executor()))
.thenApply(aggResp -> {
// try-with-resources here ensures the content is released
// if it is a pooled HttpData, or otherwise it's no-op.
try (HttpData content = aggResp.content()) {
if (!aggResp.status().equals(HttpStatus.OK)) {
throw new IllegalStateException("Bad response");
}
try {
return OBJECT_MAPPER.readValue(content.toInputStream(), Foo.class);
} catch (IOException e) {
throw new IllegalArgumentException("Bad JSON: " + content.toStringUtf8());
}
}
});
In the above example, it is the initial try (HttpData content = ...)
that ensures the data
is released. Calls to methods on HttpData
will all work and can be called any number of times within
this block. If called after the block or a manual call to Bytes.close()
, these methods will fail
or corrupt data.
-
Method Summary
Modifier and TypeMethodDescriptionstatic void
Closes the given pooledBytes
.static <T> T
copyAndClose
(T obj) static <T> T
touch
(T obj) static <T> T
-
Method Details
-
close
- Parameters:
obj
- maybe anBytes
to close
-
touch
public static <T> T touch(T obj) CallsByteBuf.touch(Object)
on the specifiedBytes
' underlyingByteBuf
. Uses the specifiedBytes
as a hint. Does nothing if it's not a pooledBytes
.- Parameters:
obj
- maybe a pooledBytes
to touch its underlyingByteBuf
-
touch
CallsByteBuf.touch(Object)
on the specifiedBytes
's underlyingByteBuf
. Does nothing if it's not a pooledBytes
.- Parameters:
obj
- maybe a pooledBytes
to touch its underlyingByteBuf
hint
- the hint to specify when callingByteBuf.touch(Object)
-
copyAndClose
public static <T> T copyAndClose(T obj) Creates an unpooled copy of the givenHttpData
and closes the givenHttpData
. Returns the given object as is if it's not a pooledHttpData
. This method is useful when you need to pass your pooledHttpData
instances to the third party who is not capable of handling pooledHttpData
.- Parameters:
obj
- maybe anHttpData
to copy
-