public static PendingWrite NewInstance(object msg, int size, TaskCompletionSource promise)
            {
                PendingWrite write = Pool.Take();

                write.Add(msg, size);
                write.Promise = promise;
                return(write);
            }
Exemplo n.º 2
0
        /// <summary>Add the given <c>msg</c> and returns <see cref="Task" /> for completion of processing <c>msg</c>.</summary>
        public void Add(object msg, IPromise promise)
        {
            Debug.Assert(_ctx.Executor.InEventLoop);
            if (msg is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.msg);
            }

            int messageSize = _estimatorHandle.Size(msg);

            if (messageSize < 0)
            {
                // Size may be unknow so just use 0
                messageSize = 0;
            }
            PendingWrite currentTail = _tail;

            if (currentTail is object)
            {
                bool canBundle = CanBatch(msg, messageSize, currentTail.Size);
                if (canBundle)
                {
                    currentTail.Add(msg, messageSize);
                    if (!promise.IsVoid)
                    {
                        currentTail.Promise.Task.LinkOutcome(promise);
                    }
                    return;
                }
            }

            PendingWrite write;

            if (promise.IsVoid || promise is SimplePromiseAggregator)
            {
                var headPromise = _ctx.NewPromise();
                headPromise.Task.LinkOutcome(promise);
                write = PendingWrite.NewInstance(msg, messageSize, headPromise);
            }
            else
            {
                write = PendingWrite.NewInstance(msg, messageSize, promise);
            }
            if (currentTail is null)
            {
                _tail = _head = write;
            }
            else
            {
                currentTail.Next = write;
                _tail            = write;
            }
            _size++;
            // We need to guard against null as channel.Unsafe.OutboundBuffer may returned null
            // if the channel was already closed when constructing the PendingWriteQueue.
            // See https://github.com/netty/netty/issues/3967
            _buffer?.IncrementPendingOutboundBytes(messageSize);
        }
        /// <summary>Add the given <c>msg</c> and returns <see cref="Task" /> for completion of processing <c>msg</c>.</summary>
        public Task Add(object msg)
        {
            Contract.Assert(this.ctx.Executor.InEventLoop);
            Contract.Requires(msg != null);

            int messageSize = this.estimatorHandle.Size(msg);

            if (messageSize < 0)
            {
                // Size may be unknow so just use 0
                messageSize = 0;
            }
            PendingWrite currentTail = this.tail;

            if (currentTail != null)
            {
                bool canBundle = this.CanBatch(msg, messageSize, currentTail.Size);
                if (canBundle)
                {
                    currentTail.Add(msg, messageSize);
                    return(currentTail.Promise.Task);
                }
            }

            var          promise = new TaskCompletionSource();
            PendingWrite write   = PendingWrite.NewInstance(msg, messageSize, promise);

            if (currentTail == null)
            {
                this.tail = this.head = write;
            }
            else
            {
                currentTail.Next = write;
                this.tail        = write;
            }
            this.size++;
            // We need to guard against null as channel.Unsafe.OutboundBuffer may returned null
            // if the channel was already closed when constructing the PendingWriteQueue.
            // See https://github.com/netty/netty/issues/3967
            this.buffer?.IncrementPendingOutboundBytes(messageSize);
            return(promise.Task);
        }