Skip to content

[FLINK-39103][runtime] Tolerate errors when recycling buffer from input channel notification if it had errors already#27624

Open
rkhachatryan wants to merge 3 commits intoapache:masterfrom
rkhachatryan:f39103
Open

[FLINK-39103][runtime] Tolerate errors when recycling buffer from input channel notification if it had errors already#27624
rkhachatryan wants to merge 3 commits intoapache:masterfrom
rkhachatryan:f39103

Conversation

@rkhachatryan
Copy link
Contributor

@rkhachatryan rkhachatryan commented Feb 17, 2026

The first 3 commits are from #27619 - please ignore them while reviewing.

Example failure stack trace:

java.lang.RuntimeException: org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException: Error at remote task manager 'localhost/127.0.0.1:40903 [ 8b99efa6-f87f-4fba-9d9d-9b8497d249fa ] '.
	at org.apache.flink.util.ExceptionUtils.rethrow(ExceptionUtils.java:321) ~[flink-core-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.partition.consumer.BufferManager.recycle(BufferManager.java:237) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.buffer.NetworkBuffer.deallocate(NetworkBuffer.java:189) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.shaded.netty4.io.netty.buffer.AbstractReferenceCountedByteBuf.handleRelease(AbstractReferenceCountedByteBuf.java:151) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:141) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.runtime.io.network.buffer.NetworkBuffer.recycleBuffer(NetworkBuffer.java:161) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.api.serialization.SpillingAdaptiveSpanningRecordDeserializer.clear(SpillingAdaptiveSpanningRecordDeserializer.java:140) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.releaseDeserializer(AbstractStreamTaskNetworkInput.java:328) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.close(AbstractStreamTaskNetworkInput.java:320) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.runtime.io.StreamTaskNetworkInput.close(StreamTaskNetworkInput.java:142) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.runtime.io.StreamOneInputProcessor.close(StreamOneInputProcessor.java:88) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.runtime.tasks.StreamTask.cleanUpInternal(StreamTask.java:1112) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.util.IOUtils.closeAll(IOUtils.java:257) ~[flink-core-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.core.fs.AutoCloseableRegistry.doClose(AutoCloseableRegistry.java:83) ~[flink-core-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.util.AbstractAutoCloseableRegistry.close(AbstractAutoCloseableRegistry.java:127) ~[flink-core-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.runtime.tasks.StreamTask.cleanUp(StreamTask.java:1103) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.taskmanager.Task.lambda$restoreAndInvoke$2(Task.java:972) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.taskmanager.Task.runWithSystemExitMonitoring(Task.java:987) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.taskmanager.Task.lambda$restoreAndInvoke$3(Task.java:972) [flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.util.IOUtils.closeAll(IOUtils.java:257) ~[flink-core-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.core.fs.AutoCloseableRegistry.doClose(AutoCloseableRegistry.java:83) ~[flink-core-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.util.AbstractAutoCloseableRegistry.close(AbstractAutoCloseableRegistry.java:127) ~[flink-core-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:808) [flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.taskmanager.Task.run(Task.java:579) [flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at java.base/java.lang.Thread.run(Thread.java:833) [?:?]
Caused by: org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException: Error at remote task manager 'localhost/127.0.0.1:40903 [ 8b99efa6-f87f-4fba-9d9d-9b8497d249fa ] '.
	at org.apache.flink.runtime.io.network.netty.CreditBasedPartitionRequestClientHandler.decodeMsg(CreditBasedPartitionRequestClientHandler.java:333) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.netty.CreditBasedPartitionRequestClientHandler.channelRead(CreditBasedPartitionRequestClientHandler.java:197) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.shaded.netty4.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:356) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.runtime.io.network.netty.NettyMessageClientDecoderDelegate.channelRead(NettyMessageClientDecoderDelegate.java:112) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.shaded.netty4.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:356) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1429) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:794) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.handle(AbstractEpollChannel.java:482) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.EpollIoHandler$DefaultEpollIoRegistration.handle(EpollIoHandler.java:317) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.EpollIoHandler.processReady(EpollIoHandler.java:514) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.EpollIoHandler.run(EpollIoHandler.java:459) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.SingleThreadIoEventLoop.runIo(SingleThreadIoEventLoop.java:225) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.SingleThreadIoEventLoop.run(SingleThreadIoEventLoop.java:196) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:1193) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	... 1 more
Caused by: org.apache.flink.runtime.io.network.partition.ProducerFailedException: java.lang.Exception: java.lang.Exception: Artificial Failure
	at org.apache.flink.runtime.io.network.partition.PipelinedSubpartitionView.getFailureCause(PipelinedSubpartitionView.java:96) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.netty.CreditBasedSequenceNumberingViewReader.getFailureCause(CreditBasedSequenceNumberingViewReader.java:282) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.netty.PartitionRequestQueue.writeAndFlushNextMessageIfPossible(PartitionRequestQueue.java:325) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.netty.PartitionRequestQueue.enqueueAvailableReader(PartitionRequestQueue.java:126) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.netty.PartitionRequestQueue.addCreditOrResumeConsumption(PartitionRequestQueue.java:175) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.netty.PartitionRequestServerHandler.channelRead0(PartitionRequestServerHandler.java:115) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.runtime.io.network.netty.PartitionRequestServerHandler.channelRead0(PartitionRequestServerHandler.java:42) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.shaded.netty4.io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:356) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:356) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1429) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:794) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.handle(AbstractEpollChannel.java:482) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.EpollIoHandler$DefaultEpollIoRegistration.handle(EpollIoHandler.java:317) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.EpollIoHandler.processReady(EpollIoHandler.java:514) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.epoll.EpollIoHandler.run(EpollIoHandler.java:459) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.SingleThreadIoEventLoop.runIo(SingleThreadIoEventLoop.java:225) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.channel.SingleThreadIoEventLoop.run(SingleThreadIoEventLoop.java:196) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:1193) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	at org.apache.flink.shaded.netty4.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[flink-shaded-netty-4.2.6.Final-21.0.jar:?]
	... 1 more
Caused by: org.apache.flink.util.SerializedThrowable: java.lang.Exception: Artificial Failure
	at org.apache.flink.test.checkpointing.utils.FailingSource.run(FailingSource.java:111) ~[test-classes/:?]
	at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:107) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:68) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]
	at org.apache.flink.streaming.runtime.tasks.SourceStreamTask$LegacySourceFunctionThread.run(SourceStreamTask.java:346) ~[flink-runtime-2.3-SNAPSHOT.jar:2.3-SNAPSHOT]

@flinkbot
Copy link
Collaborator

flinkbot commented Feb 17, 2026

CI report:

Bot commands The @flinkbot bot supports the following commands:
  • @flinkbot run azure re-run the last Azure build

@@ -216,6 +221,10 @@ public void recycle(MemorySegment segment) {
if (inputChannel.isReleased()) {
globalPool.recycleUnpooledMemorySegments(Collections.singletonList(segment));
return;
} else if (inputChannel.hasError()) {
LOG.warn("Input channel has errors - recycling the buffer");
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this warn result in e2e test failure as "unexpected error" or do we only filter for ERROR level there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IIRC the script greps errors, not warnings, so it should be fine.

Copy link
Contributor

@Izeren Izeren left a comment

Choose a reason for hiding this comment

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

Thank you @rkhachatryan, I have left a couple of comments for better understanding of the problem

@@ -346,6 +346,11 @@ public long unsynchronizedGetSizeOfQueuedBuffers() {
*/
public void notifyRequiredSegmentId(int subpartitionId, int segmentId) throws IOException {}

/** Whether this input channel has encountered error. */
public boolean hasError() {
return cause.get() != null;
Copy link
Contributor

Choose a reason for hiding this comment

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

If it is not too complicated would be good to write a dedicated unit test for new public method

Copy link
Contributor Author

@rkhachatryan rkhachatryan Feb 17, 2026

Choose a reason for hiding this comment

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

I agree, I just wanted to agree on the approach first.
Other approaches are passing ignoreErrors to notifyBufferAvailable or ignoring errors coming from it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a test

@@ -216,6 +221,10 @@ public void recycle(MemorySegment segment) {
if (inputChannel.isReleased()) {
globalPool.recycleUnpooledMemorySegments(Collections.singletonList(segment));
return;
} else if (inputChannel.hasError()) {
LOG.warn("Input channel has errors - recycling the buffer");
globalPool.recycleUnpooledMemorySegments(Collections.singletonList(segment));
Copy link
Contributor

Choose a reason for hiding this comment

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

For my understanding, does every segment have only 1 input channel?
Can it happen that we would call recycleUnpooledMemorySegments on the same segment twice? If yes, is this call idempotent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, at any given time each memory segment has only one owner, and recycling it twice would cause an error.

@rkhachatryan rkhachatryan force-pushed the f39103 branch 2 times, most recently from 0042631 to 7d35eec Compare February 17, 2026 15:45
Comment on lines +327 to +328
final boolean hadError =
checkpointedInputGate.getChannel(channelInfo.getInputChannelIdx()).hasError();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In theory, recycling the buffer can also fail for other reason:

if (inputChannel.isReleased()) {
  globalPool.recycleUnpooledMemorySegments(Collections.singletonList(segment));

But I think global pool failure shouldn't be ignored.

Copy link
Member

Choose a reason for hiding this comment

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

I share the same concern you mentioned.

The current catch (Exception e) + if (hadError) would swallow all exceptions from releaseDeserializer, not just the channel error. If e.g. globalPool.recycleUnpooledMemorySegments fails while hadError=true, that failure is silently lost.

And it is dangerous if introducing new exception in the future.

@rkhachatryan rkhachatryan marked this pull request as ready for review February 17, 2026 15:49
@rkhachatryan rkhachatryan requested a review from Izeren February 17, 2026 15:50
@rkhachatryan
Copy link
Contributor Author

CI failures seem unrelated

@github-actions github-actions bot added the community-reviewed PR has been reviewed by the community. label Feb 18, 2026
…orresponding channel already had errors

On cleanup, deserializer recycles its buffers, potentially notifying the input channel.

However, if the input channel has encountered an error (such as RemoteTransportException);
then notification will fail which might cause the whol cleanup to fail
and lead to TM shutdown.
Copy link
Contributor

@Izeren Izeren left a comment

Choose a reason for hiding this comment

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

LGTM, I have added a few more comments, PTAL

LOG.warn(
"Ignoring deserializer release failure - the channel has encountered an error before");
} else {
err = e;
Copy link
Contributor

Choose a reason for hiding this comment

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

!nit, If multiple channels throw, we will only capture the last one. Maybe it would make sense to chain them like: err = ExceptionUtils.firstOrSuppressed(e, err); or similar, WDYT

Copy link
Contributor

Choose a reason for hiding this comment

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

If we do so, may make sense to add unit test covering multiple failures

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, I'll use firstOrSuppressed.
Covering this with unti tests I think is overkill though, this is not a critical information IMO

} catch (Exception e) {
if (hadError) {
LOG.warn(
"Ignoring deserializer release failure - the channel has encountered an error before");
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any channel info/task info we would like to log, so that we know where this error was coming from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, there' s actually channelInfo available - I'll add it to the log message.

@@ -316,8 +322,23 @@ public CompletableFuture<?> getAvailableFuture() {
@Override
public void close() throws IOException {
// release the deserializers . this part should not ever fail
Copy link
Contributor

Choose a reason for hiding this comment

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

🤔, this part shouldn't ever fail and we put try-catch right after. Should we update this comment explaining how can it fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, updated the comment.

public void close() throws IOException {
// release the deserializers . this part should not ever fail
// WARN: throwing an exception from this method might fail Task close procedure and
// termination th TM
Copy link
Contributor

Choose a reason for hiding this comment

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

!nit, "of the"?

Copy link
Member

@1996fanrui 1996fanrui left a comment

Choose a reason for hiding this comment

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

According the inline comment, I wonder if we should fix this at a different layer. Tracing the call chain:

BufferManager.recycle(segment)
  → buffer added back to queue              ← already recycled successfully
  → inputChannel.notifyBufferAvailable(1)    ← credit notification
    → notifyCreditAvailable()
      → checkPartitionRequestQueueInitialized()
        → checkError() → throws

The buffer is already recycled at that point. The failure comes from notifying credit to a producer whose connection is already dead — which is unnecessary.

What about skipping credit notification for errored channels instead?

// RemoteInputChannel.java
public void notifyBufferAvailable(int numAvailableBuffers) throws IOException {
    if (hasError()) {
        return;
    }
    if (numAvailableBuffers > 0 && unannouncedCredit.getAndAdd(numAvailableBuffers) == 0) {
        notifyCreditAvailable();
    }
}

This way: (1) buffer recycling is not affected, (2) global pool errors are not affected (they happen before notifyBufferAvailable in BufferManager.recycle), and (3) all code paths that recycle buffers are covered, not just close().

Comment on lines +327 to +328
final boolean hadError =
checkpointedInputGate.getChannel(channelInfo.getInputChannelIdx()).hasError();
Copy link
Member

Choose a reason for hiding this comment

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

I share the same concern you mentioned.

The current catch (Exception e) + if (hadError) would swallow all exceptions from releaseDeserializer, not just the channel error. If e.g. globalPool.recycleUnpooledMemorySegments fails while hadError=true, that failure is silently lost.

And it is dangerous if introducing new exception in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-reviewed PR has been reviewed by the community.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments