Пример #1
0
        private bool Remove(Exception cause, bool notifyWritability)
        {
            var e = _flushedEntry;

            if (e == null)
            {
                return(false);
            }
            var msg     = e.Message;
            var promise = e.Promise;
            var size    = e.PendingSize;

            RemoveEntry(e);

            if (!e.Cancelled)
            {
                // only release message, notify and decrement if it was not canceled before.
                ReferenceCountUtil.SafeRelease(msg);
                PromiseUtil.SafeSetFailure(promise, cause, Logger);
                DecrementPendingOutboundBytes(size, notifyWritability);
            }

            e.Recycle();
            return(true);
        }
Пример #2
0
        internal void Close(ClosedChannelException cause)
        {
            if (_inFail)
            {
                return;
            }

            if (!IsEmpty)
            {
                throw new InvalidOperationException("close() must be called after all flushed writes are handled.");
            }

            _inFail = true;

            try
            {
                var e = _unflushedEntry;
                while (e != null)
                {
                    // No triggering anymore events, as we are shutting down
                    if (!e.Cancelled)
                    {
                        ReferenceCountUtil.SafeRelease(e.Message);
                        PromiseUtil.SafeSetFailure(e.Promise, cause, Logger);
                    }
                    e = e.RecycleAndGetNext();
                }
            }
            finally
            {
                _inFail = false;
            }
        }
Пример #3
0
        public bool Remove()
        {
            var e = _flushedEntry;

            if (e == null)
            {
                return(false);
            }
            var msg     = e.Message;
            var promise = e.Promise;
            var size    = e.PendingSize;

            RemoveEntry(e);

            if (!e.Cancelled)
            {
                // only release message, notify and decrement if it was not canceled before.
                ReferenceCountUtil.SafeRelease(msg);
                PromiseUtil.SafeSetSuccess(promise, Logger);
                DecrementPendingOutboundBytes(size, true);
            }

            e.Recycle();
            return(true);
        }
Пример #4
0
        /**
         * Releases all messages and destroys the {@link Queue}.
         */
        void Destroy()
        {
            if (_queue is object)
            {
                if (_queue.NonEmpty)
                {
#if DEBUG
                    if (Logger.TraceEnabled)
                    {
                        Logger.NonEmptyQueue(_queue);
                    }
#endif

                    if (_releaseMessages)
                    {
                        while (_queue.TryDequeue(out object msg))
                        {
                            ReferenceCountUtil.SafeRelease(msg);
                        }
                    }
                }

                _queue.Recycle();
                _queue = null;
            }
        }
Пример #5
0
 public void Dispose()
 {
     if (this.Payload != null)
     {
         ReferenceCountUtil.SafeRelease(this.Payload);
     }
 }
 static void ReleaseMessages(List <object> messages)
 {
     foreach (object msg in messages)
     {
         ReferenceCountUtil.SafeRelease(msg);
     }
 }
Пример #7
0
        /// <summary>
        /// Removes all pending write operations, and fail them with the given <see cref="Exception"/>. The messages
        /// will be released via <see cref="ReferenceCountUtil.SafeRelease(object)"/>.
        /// </summary>
        /// <param name="cause">The <see cref="Exception"/> to fail with.</param>
        public void RemoveAndFailAll(Exception cause)
        {
            Debug.Assert(_ctx.Executor.InEventLoop);
            if (cause is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.cause);
            }

            // It is possible for some of the failed promises to trigger more writes. The new writes
            // will "revive" the queue, so we need to clean them up until the queue is empty.
            for (PendingWrite write = _head; write is object; write = _head)
            {
                _head  = _tail = null;
                _size  = 0;
                _bytes = 0;
                while (write is object)
                {
                    PendingWrite next = write.Next;
                    ReferenceCountUtil.SafeRelease(write.Msg);
                    IPromise promise = write.Promise;
                    Recycle(write, false);
                    Util.SafeSetFailure(promise, cause, Logger);
                    write = next;
                }
            }
            AssertEmpty();
        }
        bool Remove0(Exception cause, bool notifyWritability)
        {
            Entry e = this.flushedEntry;

            if (e == null)
            {
                this.ClearNioBuffers();
                return(false);
            }
            object msg = e.Message;

            TaskCompletionSource promise = e.Promise;
            int size = e.PendingSize;

            this.RemoveEntry(e);

            if (!e.Cancelled)
            {
                // only release message, fail and decrement if it was not canceled before.
                ReferenceCountUtil.SafeRelease(msg);
                SafeFail(promise, cause);
                this.DecrementPendingOutboundBytes(size, false, notifyWritability);
            }

            // recycle the entry
            e.Recycle();

            return(true);
        }
        public void Handle(MessageWithFeedback messageWithFeedback)
        {
            IChannelHandlerContext context = this.capturedContext;
            IMessage message = messageWithFeedback.Message;

            try
            {
                Contract.Assert(message != null);

                PerformanceCounters.MessagesReceivedPerSecond.Increment();

                this.PublishToClientAsync(context, messageWithFeedback).OnFault(ShutdownOnPublishFaultAction, context);
                message = null;
            }
            catch (MessagingException ex)
            {
                this.ShutdownOnReceiveError(ex);
            }
            catch (Exception ex)
            {
                ShutdownOnError(context, ReceiveProcessingScope, ex);
            }
            finally
            {
                if (message != null)
                {
                    ReferenceCountUtil.SafeRelease(message.Payload);
                }
            }
        }
Пример #10
0
        bool Remove0(Exception cause, bool notifyWritability)
        {
            Entry e = this.flushedEntry;

            if (e == null)
            {
                return(false);
            }
            object msg = e.Message;

            TaskCompletionSource promise = e.Promise;
            int size = e.PendingSize;

            this.RemoveEntry(e);

            if (!e.Cancelled)
            {
                // only release message, fail and decrement if it was not canceled before.
                ReferenceCountUtil.SafeRelease(msg);

                Util.SafeSetFailure(promise, cause);
                if (promise != TaskCompletionSource.Void && !promise.TrySetException(cause))
                {
                    ChannelEventSource.Log.Warning(string.Format("Failed to mark a promise as failure because it's done already: {0}", promise), cause);
                }
                this.DecrementPendingOutboundBytes(size, false, notifyWritability);
            }

            // recycle the entry
            e.Recycle();

            return(true);
        }
        public void Close()
        {
            switch (this.state)
            {
            case State.Idle:
                this.state = State.Closed;
                this.closedPromise.TryComplete();
                break;

            case State.Processing:
                this.state = State.Closed;
                Queue <T> queue = this.backlogQueue;
                while (queue.Count > 0)
                {
                    T packet = queue.Dequeue();
                    ReferenceCountUtil.SafeRelease(packet);
                }
                break;

            case State.Closed:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #12
0
        /// <summary>
        /// Will remove the current message, mark its {@link ChannelPromise} as success and return {@code true}. If no
        /// flushed message exists at the time this method is called it will return {@code false} to signal that no more
        /// messages are ready to be handled.
        /// </summary>
        public bool Remove()
        {
            Entry e = this.flushedEntry;

            if (e == null)
            {
                return(false);
            }
            object msg = e.Message;

            TaskCompletionSource promise = e.Promise;
            int size = e.PendingSize;

            this.RemoveEntry(e);

            if (!e.Cancelled)
            {
                // only release message, notify and decrement if it was not canceled before.
                ReferenceCountUtil.SafeRelease(msg);
                Util.SafeSetSuccess(promise);
                this.DecrementPendingOutboundBytes(size, false, true);
            }

            // recycle the entry
            e.Recycle();

            return(true);
        }
Пример #13
0
        /// <summary>设置返回值
        /// </summary>
        private void HandleReceivedPack(ReceivedPackage package)
        {
            try
            {
                //返回为Strem,需要逐步进行解析

                _resp.Header = new FastDFSHeader(package.Length, package.Command, package.Status);

                if (!_context.IsOutputStream)
                {
                    _resp.LoadContent(Configuration, package.Body);
                }

                _context = null;
                _tcs.SetResult(_resp);

                //释放
                ReferenceCountUtil.SafeRelease(package);
            }
            catch (Exception ex)
            {
                Logger.LogError("接收返回信息出错! {0}", ex);
                throw;
            }
        }
Пример #14
0
        static void HandleSslStreamWrite(IAsyncResult result)
        {
            var self = (TlsHandler)result.AsyncState;
            TaskCompletionSource <int> tcs = self.sslStreamWriteQueue.Dequeue();

            try
            {
                self.sslStream.EndWrite(result);

                tcs.TrySetResult(0);
            }
            catch (Exception ex)
            {
                tcs.TrySetException(ex);
            }
            finally
            {
                ReferenceCountUtil.SafeRelease(tcs.Task.AsyncState); // releasing buffer

                if (self.sslStreamWriteQueue.Count == 0)
                {
                    self.state &= ~State.WriteInProgress;
                }
                else
                {
                    // post to executor to break the stack (avoiding stack overflow)
                    self.capturedContext.Channel.EventLoop.Execute(WriteFromQueueAction, self);
                    // todo: evaluate if separate path for sync completion makes sense
                }
            }
        }
        // Provides handler for Direct Methods intended as messages to a currently connected device.
        // The method will deserialize the intended message from the method request and attempt to
        // send it along via an existing topic.
        private Task <MethodResponse> OnSendMessageToDevice(MethodRequest methodRequest, object userContext)
        {
            int status = 200;

            string identifier = this.GenerateMessageId();

            // Turn this method call into a message.
            Message message = new Message(methodRequest.Data);

            IByteBuffer messagePayload = null;

            try
            {
                messagePayload = this.allocator.Buffer(methodRequest.Data.Length, methodRequest.Data.Length);
                messagePayload.WriteBytes(methodRequest.Data);

                var msg = new IotHubTransformedClientMessage(message, messagePayload, identifier, DateTime.UtcNow);
                msg.Properties[TemplateParameters.DeviceIdTemplateParam] = this.deviceId;

                msg.Properties["mqtt-qos"] = "2";

                string address;
                if (!this.messageAddressConverter.TryDeriveAddress(msg, out address))
                {
                    messagePayload.Release();
                    throw new InvalidDataException();
                }

                msg.Address = address;

                this.messagingChannel.Handle(msg);

                message        = null; // ownership has been transferred to messagingChannel
                messagePayload = null;

                // TODO : Wait for ack from device
            }
            catch (Exception ex)
            {
                // Any error is a failure; probably don’t want to close the channel.
                this.messagingChannel.Close(ex);
                status = 500;
            }
            finally
            {
                message?.Dispose();
                if (messagePayload != null)
                {
                    ReferenceCountUtil.SafeRelease(messagePayload);
                }
            }

            string result = "{\"result\":\"Executed: " + methodRequest.Name + "\"}";

            return(Task.FromResult(new MethodResponse(System.Text.Encoding.UTF8.GetBytes(result), status)));

            // Should the delegate use async methods then the return value should be as follows.
            //return new MethodResponse(System.Text.Encoding.UTF8.GetBytes(result), status);
        }
        private string Dequeue(int numBytes, IPromise aggregatePromise)
        {
            IByteBuffer removed = writeQueue.Remove(numBytes, aggregatePromise);
            string      result  = removed.ToString(Encoding.ASCII);

            ReferenceCountUtil.SafeRelease(removed);
            return(result);
        }
Пример #17
0
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            //接收到消息
            //调用服务器端接口
            //将返回值编码
            //将返回值发送到客户端
            if (message is IByteBuffer buffer)
            {
                var bytes = new byte[buffer.ReadableBytes];
                buffer.ReadBytes(bytes);
                var transportMessage = bytes.Desrialize <TransportMessage>();
                context.FireChannelRead(transportMessage);
                ReferenceCountUtil.SafeRelease(buffer);

                var rpc = transportMessage.GetContent <RemoteInvokeMessage>();

                var methodName    = rpc.Method;
                var arguments     = rpc.Arguments;
                var types         = (from item in arguments select item.GetType()).ToArray();
                var remoteInvoker = new RemoteInvokeResultMessage
                {
                    ExceptionMessage = "",
                    StatusCode       = 200
                };
                try
                {
                    var method = _service.GetType().GetMethod(methodName, types);
                    var result = method.Invoke(_service, arguments);

                    if (method.ReturnType == typeof(Task))
                    {
                        remoteInvoker.Result = null;
                    }
                    else if (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
                    {
                        var awaiter = result.GetType().GetMethod("GetAwaiter").Invoke(result, new object[] { });
                        var value   = awaiter.GetType().GetMethod("GetResult").Invoke(awaiter, new object[] { });
                        remoteInvoker.Result = value;
                    }
                    else
                    {
                        remoteInvoker.Result = result;
                    }
                }
                catch (Exception ex)
                {
                    remoteInvoker.ExceptionMessage = ex.Message;
                    remoteInvoker.StatusCode       = 500;
                    Logger().LogError(ex, ex.Message);
                }
                var resultData = TransportMessage.CreateInvokeResultMessage(transportMessage.Id, remoteInvoker);
                var sendByte   = resultData.Serialize();
                var sendBuffer = Unpooled.WrappedBuffer(sendByte);
                context.WriteAndFlushAsync(sendBuffer).GetAwaiter().GetResult();
            }
            ReferenceCountUtil.SafeRelease(message);
        }
Пример #18
0
        protected override void Encode(IChannelHandlerContext context, IByteBuf message, List <object> output)
        {
            base.Encode(context, message, _temporaryOutput);
            var lengthFrame = (IByteBuf)_temporaryOutput[0];
            var combined    = lengthFrame.WriteBytes(message);

            ReferenceCountUtil.SafeRelease(message, 1); // ready to release it - bytes have been copied
            output.Add(combined.Retain());
            _temporaryOutput.Clear();
        }
Пример #19
0
 public override void ChannelRead(IChannelHandlerContext context, object message)
 {
     if (message is IByteBuffer buffer)
     {
         var bytes = new byte[buffer.ReadableBytes];
         buffer.ReadBytes(bytes);
         var transportMessage = bytes.Desrialize <TransportMessage>();
         _receviedAction(context, transportMessage);
     }
     ReferenceCountUtil.SafeRelease(message);
 }
Пример #20
0
 public override void ChannelRead(IChannelHandlerContext context, object message)
 {
     if (AbstractByteBuf.ByteBufComparer.Equals(_expectedData, message as IByteBuf))
     {
         ReferenceCountUtil.SafeRelease(message);
         _latch.Signal();
     }
     else
     {
         base.ChannelRead(context, message);
     }
 }
Пример #21
0
 public override void ChannelRead(IChannelHandlerContext context, object message)
 {
     this.lastReceivedMessage = message;
     try
     {
         this.ContinueScenarioExecution(context);
     }
     finally
     {
         ReferenceCountUtil.SafeRelease(message);
     }
 }
Пример #22
0
        void Wrap(IChannelHandlerContext context)
        {
            Contract.Assert(context == this.capturedContext);

            IByteBuffer buf = null;

            try
            {
                while (true)
                {
                    List <object> messages = this.pendingUnencryptedWrites.Current;
                    if (messages == null || messages.Count == 0)
                    {
                        break;
                    }

                    if (messages.Count == 1)
                    {
                        buf = (IByteBuffer)messages[0];
                    }
                    else
                    {
                        buf = context.Allocator.Buffer((int)this.pendingUnencryptedWrites.CurrentSize);
                        foreach (IByteBuffer buffer in messages)
                        {
                            buffer.ReadBytes(buf, buffer.ReadableBytes);
                            buffer.Release();
                        }
                    }
                    buf.ReadBytes(this.sslStream, buf.ReadableBytes); // this leads to FinishWrap being called 0+ times
                    buf.Release();

                    TaskCompletionSource promise = this.pendingUnencryptedWrites.Remove();
                    Task task = this.lastContextWriteTask;
                    if (task != null)
                    {
                        task.LinkOutcome(promise);
                        this.lastContextWriteTask = null;
                    }
                    else
                    {
                        promise.TryComplete();
                    }
                }
            }
            catch (Exception ex)
            {
                ReferenceCountUtil.SafeRelease(buf);
                this.HandleFailure(ex);
                throw;
            }
        }
Пример #23
0
 public override void UserEventTriggered(IChannelHandlerContext context, object evt)
 {
     if (evt is IdleStateEvent idleStateEvent)
     {
         if (idleStateEvent.State == IdleState.AllIdle)
         {
             var pingPacket = new PingPacket();
             //release?
             ReferenceCountUtil.SafeRelease(idleStateEvent);
             context.WriteAndFlushAsync(pingPacket);
         }
     }
 }
 public override void Discard(Exception ex)
 {
     try
     {
         // Need to protect ourselves from any exception being thrown in the future handler from the application
         _batches.ToList().ForEach(x => x.Value.FirstCallback(null, ex));
     }
     catch (Exception t)
     {
         _log.Warning($"[{TopicName}] [{ProducerName}] Got exception while completing the callback. Error: {t}");
     }
     _batches.ToList().ForEach(x => ReferenceCountUtil.SafeRelease(x.Value.BatchedMessageMetadataAndPayload));
     Clear();
 }
Пример #25
0
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            var buf = ((IByteBuffer)message);

            if (buf.ReadableBytes > 0)
            {
                // no need to copy the byte buffer contents; ByteString does that automatically
                var bytes = ByteString.CopyFrom(buf.Array, buf.ArrayOffset + buf.ReaderIndex, buf.ReadableBytes);
                NotifyListener(new InboundPayload(bytes));
            }

            // decrease the reference count to 0 (releases buffer)
            ReferenceCountUtil.SafeRelease(message);
        }
        private static Task SuccessAnswer(params object[] args)
        {
            if (args != null)
            {
                foreach (var item in args)
                {
                    ReferenceCountUtil.SafeRelease(item);
                }
            }
            var promise = NewPromise();

            promise.Complete();
            return(promise.Task);
        }
Пример #27
0
        internal void Close(ClosedChannelException cause)
        {
            if (this.inFail)
            {
                this.channel.EventLoop.Execute((buf, ex) => ((ChannelOutboundBuffer)buf).Close((ClosedChannelException)ex),
                                               this, cause);
                return;
            }

            this.inFail = true;

            if (this.channel.Open)
            {
                throw new InvalidOperationException("close() must be invoked after the channel is closed.");
            }

            if (!this.IsEmpty)
            {
                throw new InvalidOperationException("close() must be invoked after all flushed writes are handled.");
            }

            // Release all unflushed messages.
            try
            {
                Entry e = this.unflushedEntry;
                while (e != null)
                {
                    // Just decrease; do not trigger any events via DecrementPendingOutboundBytes()
                    int size = e.PendingSize;
                    Interlocked.Add(ref this.totalPendingSize, -size);

                    if (!e.Cancelled)
                    {
                        ReferenceCountUtil.SafeRelease(e.Message);
                        Util.SafeSetFailure(e.Promise, cause, Logger);
                        if (e.Promise != TaskCompletionSource.Void && !e.Promise.TrySetException(cause))
                        {
                            Logger.Warn($"Failed to mark a promise as failure because it's done already: {e.Promise}", cause);
                        }
                    }
                    e = e.RecycleAndGetNext();
                }
            }
            finally
            {
                this.inFail = false;
            }
            this.ClearNioBuffers();
        }
 protected override void Dispose(bool disposing)
 {
     if (this.releaseReferenceOnClosure)
     {
         this.releaseReferenceOnClosure = false;
         if (disposing)
         {
             this.buffer.Release();
         }
         else
         {
             ReferenceCountUtil.SafeRelease(this.buffer);
         }
     }
 }
Пример #29
0
            public override void ChannelRead(IChannelHandlerContext context, object message)
            {
                var count = _latch.CurrentCount;

                if ((AbstractByteBuf.ByteBufComparer.Equals(_expectedData1, message as IByteBuf) && count == 2) ||
                    (AbstractByteBuf.ByteBufComparer.Equals(_expectedData2, message as IByteBuf) && count == 1))
                {
                    Logger.Info("Received message");
                    ReferenceCountUtil.SafeRelease(message);
                    _latch.Signal();
                }
                else
                {
                    base.ChannelRead(context, message);
                }
            }
Пример #30
0
        /// <summary>
        ///     Removes a pending write operation and release it's message via {@link ReferenceCountUtil#safeRelease(Object)}.
        /// </summary>
        /// <returns><seealso cref="TaskCompletionSource" /> of the pending write or <c>null</c> if the queue is empty.</returns>
        public TaskCompletionSource Remove()
        {
            Contract.Assert(this.ctx.Executor.InEventLoop);

            PendingWrite write = this.head;

            if (write == null)
            {
                return(null);
            }
            TaskCompletionSource promise = write.Promise;

            ReferenceCountUtil.SafeRelease(write.Msg);
            this.Recycle(write, true);
            return(promise);
        }