Release ByteBuf on channel write failure in ReactorNettyClient#704
Open
bugs84 wants to merge 1 commit into
Open
Release ByteBuf on channel write failure in ReactorNettyClient#704bugs84 wants to merge 1 commit into
bugs84 wants to merge 1 commit into
Conversation
When a Netty channel write fails (e.g. broken connection, RST packet), the ByteBuf produced by FrontendMessage.encode() was never released, causing a direct memory leak. The fix separates encode from send: each ByteBuf is now individually sent via connection.outbound().send(Mono.just(buf)).then(), with doOnError and doOnCancel hooks that release the ByteBuf if its reference count is still positive. The refCnt check prevents double-release because Netty's pipeline releases the ByteBuf automatically on successful write. Both locations are fixed: - The request pipeline (constructor) - The close() method (Terminate message) Reproducer: https://github.com/bugs84/r2dbc-postgresql-bytebuf-leak-reproducer Fixes pgjdbcgh-580 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a Netty channel write fails (broken connection, RST packet, connection refused), the
ByteBufproduced byFrontendMessage.encode()is never released, causing a direct memory leak detectable by Netty'sResourceLeakDetector.Root Cause
All 21
FrontendMessage.encode()implementations useMono.fromSupplier()with no cleanup hook.ReactorNettyClientsubscribes toencode()and passes the resultingByteBuftoconnection.outbound().send(). When the channel write fails, reactor-netty does not release the ByteBuf —and neither does
ReactorNettyClient.Fix
Separate encode from send: materialize the
ByteBuffirst viaFlux.from(encode()), then write it withdoOnErroranddoOnCancelhooks that release the buffer if the write fails or is cancelled.The refCnt() > 0 check prevents double-release — on successful write, Netty's channel pipeline already releases the buffer.
Fixed in both locations:
Why consumer-side fix (not producer-side)
Reproducer
Full reproducer with deterministic proof (no Docker needed) and integration tests:
https://github.com/bugs84/r2dbc-postgresql-bytebuf-leak-reproducer
References
Fixes #580
Related: #393, #248