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); }
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; } }
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); }
/** * 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; } }
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); } }
/// <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); } } }
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(); } }
/// <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); }
/// <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; } }
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); }
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); }
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(); }
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); }
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); } }
public override void ChannelRead(IChannelHandlerContext context, object message) { this.lastReceivedMessage = message; try { this.ContinueScenarioExecution(context); } finally { ReferenceCountUtil.SafeRelease(message); } }
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; } }
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(); }
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); }
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); } } }
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); } }
/// <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); }