You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Request chunks emitted in the content publisher after the response is completed are not released, this triggers LEAK warning messages.
Any endpoint that returns a response instantly would reproduce this behavior.
Note that this is a regression introduced by #1830, and was originally fixed in #912
Reproduce
Any endpoint that returns a response without consuming its payload.
The example below invokes System.gc() to expose the LEAK warning message.
The chunks are emitted after routing, so this requires two invocation to trigger the LEAK warning message.
Invoke the endpoint twice:
curl -sSf http://localhost:8080/health -X GET -H "Content-Type: application/json" -d {}
curl -sSf http://localhost:8080/health -X GET -H "Content-Type: application/json" -d {}
Any HTTP method can be used, GET is only used as an example, but PUT or POST would work as well.
In the logs you should see:
WARNING: LEAK: RequestChunk.release() was not called before it was garbage collected. While the Reactive WebServer is designed to automatically release all the RequestChunks, it still comes with a considerable performance penalty and a demand for a large memory space (depending on expected throughput, it might require even more than 2GB). As such the users are strongly advised to release all the RequestChunk instances explicitly when they're not needed.
Fix
The following changes fix the issue:
diff --gita/webserver/webserver/src/main/java/io/helidon/webserver/ForwardingHandler.javab/webserver/webserver/src/main/java/io/helidon/webserver/ForwardingHandler.javaindexe72bf391a..6e967f745100644
--- a/webserver/webserver/src/main/java/io/helidon/webserver/ForwardingHandler.java
+++ b/webserver/webserver/src/main/java/io/helidon/webserver/ForwardingHandler.java@@ -21,6 +21,7@@importjava.util.Iterator;
importjava.util.Map;
importjava.util.Optional;
importjava.util.Queue;
+importjava.util.concurrent.Flow;
importjava.util.concurrent.atomic.AtomicLong;
importjava.util.logging.Logger;
@@ -196,7 +197,25@@publicclassForwardingHandlerextendsSimpleChannelInboundHandler<Object> {
if (queue.release()) {
queues.remove(queue);
}
- publisherRef.clearBuffer(DataChunk::release);
+ publisherRef.subscribe(newFlow.Subscriber<DataChunk>() {
+ @Override
+ publicvoidonSubscribe(Flow.Subscriptionsubscription) {
+ subscription.request(Long.MAX_VALUE);
+ }
+
+ @Override
+ publicvoidonNext(DataChunkitem) {
+ item.release();
+ }
+
+ @Override
+ publicvoidonError(Throwablethrowable) {
+ }
+
+ @Override
+ publicvoidonComplete() {
+ }
+ });
// Enable auto-read only after response has been completed// to avoid a race condition with the next response
The text was updated successfully, but these errors were encountered:
Request chunks emitted in the content publisher after the response is completed are not released, this triggers LEAK warning messages.
Any endpoint that returns a response instantly would reproduce this behavior.
Note that this is a regression introduced by #1830, and was originally fixed in #912
Reproduce
Any endpoint that returns a response without consuming its payload.
The example below invokes
System.gc()
to expose the LEAK warning message.The chunks are emitted after routing, so this requires two invocation to trigger the LEAK warning message.
Invoke the endpoint twice:
Any HTTP method can be used,
GET
is only used as an example, butPUT
orPOST
would work as well.In the logs you should see:
Fix
The following changes fix the issue:
The text was updated successfully, but these errors were encountered: