Exemplo n.º 1
0
        /// <inheritdoc />
        public override void Write(IChannelHandlerContext ctx, object msg, IPromise promise)
        {
            ThreadLocalObjectList output = null;

            try
            {
                if (AcceptOutboundMessage(msg))
                {
                    output = ThreadLocalObjectList.NewInstance();
                    var cast = (T)msg;
                    try
                    {
                        Encode(ctx, cast, output);
                    }
                    finally
                    {
                        _ = ReferenceCountUtil.Release(cast);
                    }

                    if (0u >= (uint)output.Count)
                    {
                        CThrowHelper.ThrowEncoderException_MustProduceAtLeastOneMsg(GetType());
                    }
                }
                else
                {
                    _ = ctx.WriteAsync(msg, promise);
                }
            }
            catch (EncoderException)
            {
                throw;
            }
            catch (Exception ex)
            {
                CThrowHelper.ThrowEncoderException(ex); // todo: we don't have a stack on EncoderException but it's present on inner exception.
            }
            finally
            {
                if (output is object)
                {
                    try
                    {
                        int lastItemIndex = output.Count - 1;
                        if (0u >= (uint)lastItemIndex)
                        {
                            _ = ctx.WriteAsync(output[0], promise);
                        }
                        else if (lastItemIndex > 0)
                        {
                            // Check if we can use a voidPromise for our extra writes to reduce GC-Pressure
                            // See https://github.com/netty/netty/issues/2525
                            if (promise == ctx.VoidPromise())
                            {
                                WriteVoidPromise(ctx, output);
                            }
                            else
                            {
                                WritePromiseCombiner(ctx, output, promise);
                            }
                        }
                    }
                    finally
                    {
                        output.Return();
                    }
                }
            }
        }