When high concurrency under counter problems
- Dominant language
- C#
- Stars
- 4.3k
- Forks
- 1k
- PR merge metrics
- No merged PRs in 30d
Description
My business code is to implement ChannelHandlerAdapter, and then convert msg to Byte[], and when parsing byte byte arrays at high concurrency, there will be reference counter exceptions
System.ArgumentOutOfRangeException: Count must be positive and count must refer to a location within the string/array/collection.
Parameter name: count
at System.Array.IndexOf[T](T[] array, T value, Int32 startIndex, Int32 count)
at System.Collections.Generic.Queue`1.Contains(T item)
`public class SocketByteHandler: ChannelHandlerAdapter
{
readonly bool autoRelease;
public SocketByteHandler() : this(true)
{
}
protected SocketByteHandler(bool autoRelease)
{
this.autoRelease = autoRelease;
}
public bool AcceptInboundMessage(object msg) => msg is IByteBuffer;
public override void ChannelRead(IChannelHandlerContext ctx, object msg)
{
bool release = true;
try
{
if (this.AcceptInboundMessage(msg))
{
IByteBuffer imsg = (IByteBuffer)msg;
byte[] result = new byte[imsg.ReadableBytes];
imsg.ReadBytes(result,0,imsg.ReadableBytes);
this.ChannelRead0(ctx, result);
}
else
{
release = false;
ctx.FireChannelRead(msg);
}
}
finally
{
if (autoRelease && release)
{
ReferenceCountUtil.Release(msg);
}
}
}
protected virtual void ChannelRead0(IChannelHandlerContext ctx,byte[] msg)
{
}
}`
`public void Init(ServerOptions options,Func handler)
{
_options = options;
if (options.EventLoopCount > 0)
{
bossGroup = new MultithreadEventLoopGroup(options.EventLoopCount);
}
else
{
bossGroup = new MultithreadEventLoopGroup();
}
workerGroup = new MultithreadEventLoopGroup();
bootstrap = new ServerBootstrap();
bootstrap.Group(bossGroup, workerGroup);
bootstrap.Channel();
bootstrap.Option(ChannelOption.SoBacklog, _options.SoBacklog);
bootstrap.ChildOption(ChannelOption.RcvbufAllocator,new AdaptiveRecvByteBufAllocator(64,1048,65536));
bootstrap.Option(ChannelOption.TcpNodelay, true);
bootstrap.ChildOption(ChannelOption.SoKeepalive, false);
bootstrap.ChildHandler(new ActionChannelInitializer(channel =>
{
IChannelPipeline pipeline = channel.Pipeline;
pipeline.AddLast(new MTFrameDecoder(ByteOrderEnum.LittleEndian, AppConfig.ServerOptions.MaxPackLength, AppConfig.ServerOptions.HeadPosition, AppConfig.ServerOptions.HeadLength
, AppConfig.ServerOptions.LengthAdjustment, 0, true));
//pipeline.AddLast(new IdleStateHandler(300, 300, 0));
if (options.ReadTimeout > 0)
{
pipeline.AddLast("ReadTimeout", new ReadTimeoutHandler(options.ReadTimeout));
}
pipeline.AddLast(handler());
}));
}`
Contributor guide
Assessment
This issue has not been assessed yet.