Netty 4:writeAndFlush ByteBuf 和引用计数
Netty 4: writeAndFlush ByteBuf and reference count
正如doc中所说:
When an outbound (a.k.a. downstream) message reaches at the beginning
of the pipeline, Netty will release it after writing it out.
所以正常情况下,writeAndFlush调用成功后ByteBuf
的引用计数会减少
出现错误怎么办?
假设我有两个频道:firstChannel
& secondChannel
。如果 ByteBuf
发送到 firstChannel
失败,则需要发送到 secondChannel
代码示例如下。
final ChannelFuture future = firstChannel.writeAndFlush(byteBuf.asReadOnly()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
// Is the reference count decreased already before entering this method?
if (!future.isSuccess()) {
byteBuf.retain();
secondChannel.writeAndFlush(byteBuf);
}
}
});
即使出错也会减少引用计数吗?
在触发 operationComplete
之前引用计数是否已经减少?
即使失败,它也会释放缓冲区,因此您的代码将无法运行。您需要 retain()
缓冲区以确保在调用侦听器时递增计数为 1,然后在未来成功时自行递减。
像这样:
final ChannelFuture future = firstChannel.writeAndFlush(byteBuf.retain().duplicate()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
secondChannel.writeAndFlush(byteBuf);
} else {
byteBuf.release();
}
}
});
另请注意,我也调用 duplicate()
以确保我们不会修改稍后可能传递到第二个通道的缓冲区的 reader/writer 索引。
正如doc中所说:
When an outbound (a.k.a. downstream) message reaches at the beginning of the pipeline, Netty will release it after writing it out.
所以正常情况下,writeAndFlush调用成功后ByteBuf
的引用计数会减少
出现错误怎么办?
假设我有两个频道:firstChannel
& secondChannel
。如果 ByteBuf
发送到 firstChannel
失败,则需要发送到 secondChannel
代码示例如下。
final ChannelFuture future = firstChannel.writeAndFlush(byteBuf.asReadOnly()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
// Is the reference count decreased already before entering this method?
if (!future.isSuccess()) {
byteBuf.retain();
secondChannel.writeAndFlush(byteBuf);
}
}
});
即使出错也会减少引用计数吗?
在触发 operationComplete
之前引用计数是否已经减少?
即使失败,它也会释放缓冲区,因此您的代码将无法运行。您需要 retain()
缓冲区以确保在调用侦听器时递增计数为 1,然后在未来成功时自行递减。
像这样:
final ChannelFuture future = firstChannel.writeAndFlush(byteBuf.retain().duplicate()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
secondChannel.writeAndFlush(byteBuf);
} else {
byteBuf.release();
}
}
});
另请注意,我也调用 duplicate()
以确保我们不会修改稍后可能传递到第二个通道的缓冲区的 reader/writer 索引。