Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leak detection properties are added for the test execution #2461

Merged
merged 15 commits into from Oct 3, 2022

Conversation

violetagg
Copy link
Member

@violetagg violetagg commented Sep 2, 2022

  • Fix memory leaks when processing EmptyLastHttpContent
  • Avoid buffer leak by closing the HttpRequest passed to the WebSocketServerHandshaker.handshake method
  • Declare ReactorNetty#BOUNDARY as on-heap non-releasable buffer
  • Do not close the empty full message when invoking SimpleCompressionHandler out of the pipeline
  • Http2StreamBridgeServerHandler.channelRead method should use Resource.dispose() method
  • [HttpServer] Ensure Http2FrameCodec is created only when there is a need for protocol upgrade
  • [HttpClient] Ensure Http2FrameCodec.Encoder is closed when upgrade is rejected. Ensure Http2FrameCodec.Encoder is closed when Exception happened before decoding the server response
  • Fix memory leaks in tests

@violetagg violetagg added the type/enhancement A general enhancement label Sep 2, 2022
@violetagg violetagg added this to the 2.0.0-M2 milestone Sep 2, 2022
@violetagg violetagg requested a review from a team September 2, 2022 10:35
@violetagg
Copy link
Member Author

@reactor/netty-team Wait with the review please!

Copy link
Member

@pderop pderop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@violetagg violetagg marked this pull request as draft September 5, 2022 11:39
@violetagg violetagg changed the title [test] Leak detection properties are added for the test execution Leak detection properties are added for the test execution Sep 5, 2022
@violetagg
Copy link
Member Author

Rebased in order to pickup #2464

@pderop
Copy link
Member

pderop commented Sep 6, 2022

The previous commit avoids a buffer leak in the WebsocketServerOperations class.
So, In previous 4.x, in WebsocketServerOperations class the DefaultFullHttpRequest passed to the WebSocketServerHandshaker.hanshake method was using unpooled byte buffer for its empty content, and was not released, and this was not a problem in 4.x version since unpooled/unreleased buffers were not reported by the leak detector.

Now, the empty payload for the http request is allocated from the default channel allocator, so the fix just ensures that the request is closed once the handshake method has completed.

Note: This fix, as well as the one from netty/netty#12773 should fully resolve all the leaks from the WebsocketTest

@pderop
Copy link
Member

pderop commented Sep 16, 2022

Pushed a fix in 618e866 previous commit, which avoids the following memory leaks caused by the NettyOutboundTest:
(this PR will have to be rebased once the other #2484 is merged).

io.netty5.buffer.LoggingLeakCallback$LeakReport: Object life-cycle trace:
        Suppressed: io.netty5.buffer.internal.LifecycleTracer$Traceback: ALLOCATE (current acquires = 0) T-19394us.
                at io.netty5.buffer.internal.ResourceSupport.<init>(ResourceSupport.java:42)
                at io.netty5.buffer.internal.AdaptableBuffer.<init>(AdaptableBuffer.java:28)
                at io.netty5.buffer.bytebuffer.NioBuffer.<init>(NioBuffer.java:65)
                at io.netty5.buffer.bytebuffer.ByteBufferMemoryManager.createBuffer(ByteBufferMemoryManager.java:85)
                at io.netty5.buffer.bytebuffer.ByteBufferMemoryManager.recoverMemory(ByteBufferMemoryManager.java:80)
                at io.netty5.buffer.pool.PooledBufferAllocator.allocate(PooledBufferAllocator.java:321)
                at io.netty5.buffer.DefaultBufferAllocators$UncloseableBufferAllocator.allocate(DefaultBufferAllocators.java:122)
                at io.netty5.handler.stream.ChunkedNioFile.readChunk(ChunkedNioFile.java:148)
                at io.netty5.handler.stream.ChunkedNioFile.readChunk(ChunkedNioFile.java:38)
                at io.netty5.handler.stream.ChunkedWriteHandler.doFlush(ChunkedWriteHandler.java:220)
                at io.netty5.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:124)
                at io.netty5.channel.DefaultChannelHandlerContext.invokeFlush(DefaultChannelHandlerContext.java:892)
                at io.netty5.channel.DefaultChannelHandlerContext.findAndInvokeFlush(DefaultChannelHandlerContext.java:881)
                at io.netty5.channel.DefaultChannelHandlerContext.flush(DefaultChannelHandlerContext.java:865)
                at io.netty5.channel.ChannelHandler.flush(ChannelHandler.java:393)
                at io.netty5.channel.DefaultChannelHandlerContext.invokeFlush(DefaultChannelHandlerContext.java:892)
                at io.netty5.channel.DefaultChannelHandlerContext$WriteAndFlushTask.write(DefaultChannelHandlerContext.java:1268)
                at io.netty5.channel.DefaultChannelHandlerContext$AbstractWriteTask.run(DefaultChannelHandlerContext.java:1186)
                at io.netty5.channel.embedded.EmbeddedEventLoop.runTasks(EmbeddedEventLoop.java:139)
                at io.netty5.channel.embedded.EmbeddedEventLoop.execute(EmbeddedEventLoop.java:125)
                at io.netty5.channel.DefaultChannelHandlerContext.safeExecute(DefaultChannelHandlerContext.java:1093)
                at io.netty5.channel.DefaultChannelHandlerContext.write(DefaultChannelHandlerContext.java:934)
                at io.netty5.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:902)
                at io.netty5.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:919)
                at io.netty5.channel.Channel.writeAndFlush(Channel.java:311)
                at reactor.netty5.NettyOutboundTest.lambda$mockSendUsing$3(NettyOutboundTest.java:345)
                at reactor.core.publisher.MonoUsing.subscribe(MonoUsing.java:85)
                at reactor.core.publisher.Mono.subscribe(Mono.java:4379)
                at reactor.core.publisher.Mono.block(Mono.java:1698)
                at reactor.netty5.NettyOutboundTest.sendFileWithTlsUsesChunkedFile(NettyOutboundTest.java:226)
                at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
                at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
                at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
                at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
                at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
                at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
                at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
                at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)

13:14:37.225 [Cleaner-0] ERROR io.netty5.buffer.LoggingLeakCallback - LEAK: Object "buffer (1024 bytes)" was not property closed before it was garbage collected. A life-cycle back-trace (if any) is attached as suppressed exceptions. See https://netty.io/wiki/reference-counted-objects.html for more information.
io.netty5.buffer.LoggingLeakCallback$LeakReport: Object life-cycle trace:
        Suppressed: io.netty5.buffer.internal.LifecycleTracer$Traceback: ALLOCATE (current acquires = 0) T-30434us.
                at io.netty5.buffer.internal.ResourceSupport.<init>(ResourceSupport.java:42)
                at io.netty5.buffer.internal.AdaptableBuffer.<init>(AdaptableBuffer.java:28)
                at io.netty5.buffer.bytebuffer.NioBuffer.<init>(NioBuffer.java:65)
                at io.netty5.buffer.bytebuffer.ByteBufferMemoryManager.createBuffer(ByteBufferMemoryManager.java:85)
                at io.netty5.buffer.bytebuffer.ByteBufferMemoryManager.recoverMemory(ByteBufferMemoryManager.java:80)
                at io.netty5.buffer.pool.PooledBufferAllocator.allocate(PooledBufferAllocator.java:321)
                at io.netty5.buffer.DefaultBufferAllocators$UncloseableBufferAllocator.allocate(DefaultBufferAllocators.java:122)
                at io.netty5.handler.stream.ChunkedNioFile.readChunk(ChunkedNioFile.java:148)
                at io.netty5.handler.stream.ChunkedNioFile.readChunk(ChunkedNioFile.java:38)
                at io.netty5.handler.stream.ChunkedWriteHandler.doFlush(ChunkedWriteHandler.java:220)
                at io.netty5.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:124)
                at io.netty5.channel.DefaultChannelHandlerContext.invokeFlush(DefaultChannelHandlerContext.java:892)
                at io.netty5.channel.DefaultChannelHandlerContext.findAndInvokeFlush(DefaultChannelHandlerContext.java:881)
                at io.netty5.channel.DefaultChannelHandlerContext.flush(DefaultChannelHandlerContext.java:865)
                at io.netty5.channel.ChannelHandler.flush(ChannelHandler.java:393)
                at io.netty5.channel.DefaultChannelHandlerContext.invokeFlush(DefaultChannelHandlerContext.java:892)
                at io.netty5.channel.DefaultChannelHandlerContext$WriteAndFlushTask.write(DefaultChannelHandlerContext.java:1268)
                at io.netty5.channel.DefaultChannelHandlerContext$AbstractWriteTask.run(DefaultChannelHandlerContext.java:1186)
                at io.netty5.channel.embedded.EmbeddedEventLoop.runTasks(EmbeddedEventLoop.java:139)
                at io.netty5.channel.embedded.EmbeddedEventLoop.execute(EmbeddedEventLoop.java:125)
                at io.netty5.channel.DefaultChannelHandlerContext.safeExecute(DefaultChannelHandlerContext.java:1093)
                at io.netty5.channel.DefaultChannelHandlerContext.write(DefaultChannelHandlerContext.java:934)
                at io.netty5.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:902)
                at io.netty5.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:919)
                at io.netty5.channel.Channel.writeAndFlush(Channel.java:311)
                at reactor.netty5.NettyOutboundTest.lambda$mockSendUsing$3(NettyOutboundTest.java:345)
                at reactor.core.publisher.MonoUsing.subscribe(MonoUsing.java:85)
                at reactor.core.publisher.Mono.subscribe(Mono.java:4379)
                at reactor.core.publisher.Mono.block(Mono.java:1698)
                at reactor.netty5.NettyOutboundTest.sendFileWithTlsUsesChunkedFile(NettyOutboundTest.java:226)
                at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
                at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
                at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
                at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
                at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
                at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
                at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
                at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
                at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
                at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)

@pderop
Copy link
Member

pderop commented Sep 16, 2022

in c1ead0f commit, fixed the following memory leak reproduced by the TcpServerTests.retryStrategiesWhenServerFails (sendGroups ...):

16:22:52.136 [Cleaner-0] ERROR io.netty5.buffer.LoggingLeakCallback - LEAK: Object "buffer (20 bytes)" was not property closed before it was garbage collected. A life-cycle back-trace (if any) is attached as suppressed exceptions. See https://netty.io/wiki/reference-counted-objects.html for more information.
io.netty5.buffer.LoggingLeakCallback$LeakReport: Object life-cycle trace:
	Suppressed: io.netty5.buffer.internal.LifecycleTracer$Traceback: ALLOCATE (current acquires = 0) T-32464us.
		at io.netty5.buffer.internal.ResourceSupport.<init>(ResourceSupport.java:42)
		at io.netty5.buffer.internal.AdaptableBuffer.<init>(AdaptableBuffer.java:28)
		at io.netty5.buffer.bytebuffer.NioBuffer.<init>(NioBuffer.java:76)
		at io.netty5.buffer.bytebuffer.NioBuffer.newConstChild(NioBuffer.java:1215)
		at io.netty5.buffer.bytebuffer.NioBuffer.copy(NioBuffer.java:197)
		at reactor.netty5.NettyOutbound.lambda$sendGroups$5(NettyOutbound.java:237)
		at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:376)
		at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onNext(FluxConcatMap.java:251)
		at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200)
		at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200)
		at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
		at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
		at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:126)
		at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:224)
		at reactor.netty5.channel.FluxReceive.drainReceiver(FluxReceive.java:271)
		at reactor.netty5.channel.FluxReceive.onInboundNext(FluxReceive.java:366)
		at reactor.netty5.channel.ChannelOperations.onInboundNext(ChannelOperations.java:408)
		at reactor.netty5.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:93)
		at io.netty5.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:455)
		at io.netty5.channel.DefaultChannelHandlerContext.findAndInvokeChannelRead(DefaultChannelHandlerContext.java:445)
		at io.netty5.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:426)
		at io.netty5.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:280)
		at io.netty5.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:455)
		at io.netty5.channel.DefaultChannelHandlerContext.findAndInvokeChannelRead(DefaultChannelHandlerContext.java:445)
		at io.netty5.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:426)
		at io.netty5.channel.ChannelHandler.channelRead(ChannelHandler.java:235)
		at io.netty5.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:455)
		at io.netty5.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:838)
		at io.netty5.channel.AbstractChannel$ReadSink.processRead(AbstractChannel.java:1975)
		at io.netty5.channel.nio.AbstractNioByteChannel.doReadNow(AbstractNioByteChannel.java:74)
		at io.netty5.channel.AbstractChannel$ReadSink.readLoop(AbstractChannel.java:2035)
		at io.netty5.channel.AbstractChannel.readNow(AbstractChannel.java:910)
		at io.netty5.channel.nio.AbstractNioChannel.access$100(AbstractNioChannel.java:42)
		at io.netty5.channel.nio.AbstractNioChannel$1.handle(AbstractNioChannel.java:108)
		at io.netty5.channel.nio.NioHandler.processSelectedKey(NioHandler.java:506)
		at io.netty5.channel.nio.NioHandler.processSelectedKeysOptimized(NioHandler.java:489)
		at io.netty5.channel.nio.NioHandler.processSelectedKeys(NioHandler.java:430)
		at io.netty5.channel.nio.NioHandler.run(NioHandler.java:407)
		at io.netty5.channel.SingleThreadEventLoop.runIO(SingleThreadEventLoop.java:192)
		at io.netty5.channel.SingleThreadEventLoop.run(SingleThreadEventLoop.java:176)
		at io.netty5.util.concurrent.SingleThreadEventExecutor.lambda$doStartThread$4(SingleThreadEventExecutor.java:774)
		at io.netty5.util.internal.ThreadExecutorMap.lambda$apply$1(ThreadExecutorMap.java:68)
		at io.netty5.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
		at java.base/java.lang.Thread.run(Thread.java:833)

The proposed fix is closing the PREDICATE_GROUP_BOUNDARY from the NettyOutbound.sendGroups method (because it seems that the boundary was never closed).

@violetagg
Copy link
Member Author

@pderop WDYT about rebasing this one?

@pderop
Copy link
Member

pderop commented Sep 20, 2022

yes, will you do it or may I do ?

@violetagg
Copy link
Member Author

yes, will you do it or may I do ?

yep go ahead

@pderop
Copy link
Member

pderop commented Sep 20, 2022

rebased on netty5, in order to get #2484 .
now, if I'm correct we should only get some memory leaks for reactor-netty5-http module and the reactor-netty5-core module should pass (hopefully).

Can you go ahead on the suggestion you did regarding the cleaning of the PREDICATE_GROUP_BOUNDARY ? (I did not have time to investigate yet).

@violetagg
Copy link
Member Author

@pderop I decided to implement another approach for ReactorNetty#BOUNDARY. PTAL

@pderop
Copy link
Member

pderop commented Sep 20, 2022

@violetagg , this is a great improvement and optimization !
+1

@pderop
Copy link
Member

pderop commented Sep 21, 2022

the Netty PR (netty/netty#12828), if accepted and merged, will normally resolve the following leak for the HttpServerTests.nonContentStatusCodes test:

22:42:36.850 [Cleaner-0] ERROR io.netty5.buffer.LoggingLeakCallback - LEAK: Object "buffer (0 bytes)" was not property closed before it was garbage collected. A life-cycle back-trace (if any) is attached as suppressed exceptions. See https://netty.io/wiki/reference-counted-objects.html for more information.
io.netty5.buffer.LoggingLeakCallback$LeakReport: Object life-cycle trace:
	Suppressed: io.netty5.buffer.internal.LifecycleTracer$Traceback: ALLOCATE (current acquires = 0) T-66242us.
		at io.netty5.buffer.internal.ResourceSupport.<init>(ResourceSupport.java:42)
		at io.netty5.buffer.internal.AdaptableBuffer.<init>(AdaptableBuffer.java:28)
		at io.netty5.buffer.bytebuffer.NioBuffer.<init>(NioBuffer.java:65)
		at io.netty5.buffer.bytebuffer.ByteBufferMemoryManager.createBuffer(ByteBufferMemoryManager.java:85)
		at io.netty5.buffer.bytebuffer.ByteBufferMemoryManager.recoverMemory(ByteBufferMemoryManager.java:80)
		at io.netty5.buffer.pool.PooledBufferAllocator.allocate(PooledBufferAllocator.java:321)
		at io.netty5.buffer.DefaultBufferAllocators$UncloseableBufferAllocator.allocate(DefaultBufferAllocators.java:122)
		at io.netty5.handler.codec.http.EmptyLastHttpContent.<init>(EmptyLastHttpContent.java:30)
		at reactor.netty5.http.server.HttpServerOperations.onOutboundComplete(HttpServerOperations.java:632)
		at reactor.netty5.channel.ChannelOperations.onComplete(ChannelOperations.java:247)
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:209)
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:238)
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203)
		at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.accept(MonoCompletionStage.java:120)
		at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.accept(MonoCompletionStage.java:62)
		at io.netty5.util.concurrent.DefaultPromise.whenCompleteAsync0(DefaultPromise.java:1054)
		at io.netty5.util.concurrent.DefaultPromise.lambda$whenCompleteAsync$13(DefaultPromise.java:1041)
		at io.netty5.util.concurrent.DefaultFutureListeners.notifyListeners(DefaultFutureListeners.java:77)
		at io.netty5.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:454)
		at io.netty5.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:439)
		at io.netty5.util.concurrent.DefaultPromise$NotifyListeners.run(DefaultPromise.java:422)
		at io.netty5.channel.DefaultChannelHandlerContext$DefaultChannelHandlerContextAwareEventExecutor$DefaultHandlerContextRunnable.run(DefaultChannelHandlerContext.java:1502)
		at io.netty5.util.concurrent.SingleThreadEventExecutor.runTask(SingleThreadEventExecutor.java:338)
		at io.netty5.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:361)
		at io.netty5.channel.SingleThreadEventLoop.run(SingleThreadEventLoop.java:180)
		at io.netty5.util.concurrent.SingleThreadEventExecutor.lambda$doStartThread$4(SingleThreadEventExecutor.java:774)
		at io.netty5.util.internal.ThreadExecutorMap.lambda$apply$1(ThreadExecutorMap.java:68)
		at io.netty5.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
		at java.base/java.lang.Thread.run(Thread.java:833)

@violetagg
Copy link
Member Author

I rebased in order to pickup #2495

@pderop
Copy link
Member

pderop commented Sep 21, 2022

The previous commit 9e29d50 fixes a memory leak reproduced by the HttpServerTests.testIssue1978H2WithDelay test. It was caused by the Http2StreamBridgeServerHandler.channelRead method, which was using old ReferenceCountUtil.release(msg) instead of doing Resource.dispose(msg)

@violetagg
Copy link
Member Author

I rebased to pick up #2496

@violetagg
Copy link
Member Author

Rebased in order to pickup the latest Netty/Reactor Netty fixes

@violetagg violetagg requested a review from a team October 3, 2022 07:41
violetagg and others added 15 commits October 3, 2022 10:42
…ls by closing BOUNDARY in NettyOutbound.sendGroups"

This reverts commit c47ba03.
The Http2StreamBridgeServerHandler.channelRead method was still using old ReferenceCountUtil.release() instead of Resource.dispose() method.
Ensure Http2FrameCodec.Encoder is closed when Exception happened
before decoding the server response
@violetagg violetagg marked this pull request as ready for review October 3, 2022 07:45
@violetagg
Copy link
Member Author

I rebased the PR in order to resolve the conflicts
The PR is ready for a review

@violetagg violetagg requested review from a team and removed request for a team October 3, 2022 09:04
@violetagg
Copy link
Member Author

The failing tests on CI are not related

@violetagg
Copy link
Member Author

@OlegDokuka Thanks for the review!

@violetagg violetagg merged commit 2f5fa9b into netty5 Oct 3, 2022
@violetagg violetagg deleted the leak-detection-props-tests branch October 3, 2022 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants