public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { var ch = (NativeChannel)this.channel; if (!ch.Open) { return(this.CreateClosedChannelExceptionTask()); } try { if (ch.connectPromise != null) { throw new InvalidOperationException("connection attempt already made"); } ch.connectPromise = new TaskCompletionSource(remoteAddress); // Schedule connect timeout. TimeSpan connectTimeout = ch.Configuration.ConnectTimeout; if (connectTimeout > TimeSpan.Zero) { ch.connectCancellationTask = ch.EventLoop .Schedule(CancelConnect, ch, remoteAddress, connectTimeout); } ch.DoConnect(remoteAddress, localAddress); return(ch.connectPromise.Task); } catch (Exception ex) { this.CloseIfClosed(); return(TaskEx.FromException(this.AnnotateConnectException(ex, remoteAddress))); } }
public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { NativeChannel ch = this.Channel; if (!ch.Open) { return(this.CreateClosedChannelExceptionTask()); } ConnectRequest request = null; try { if (ch.connectPromise != null) { throw new InvalidOperationException("connection attempt already made"); } ch.connectPromise = new TaskCompletionSource(remoteAddress); if (localAddress != null) { ch.DoBind(localAddress); } request = new TcpConnect(this, (IPEndPoint)remoteAddress); return(ch.connectPromise.Task); } catch (Exception ex) { request?.Dispose(); this.CloseIfClosed(); return(TaskEx.FromException(this.AnnotateConnectException(ex, remoteAddress))); } }
public Task DisconnectAsync() { this.AssertEventLoop(); bool wasActive = this.channel.Active; try { this.channel.DoDisconnect(); } catch (Exception t) { this.CloseIfClosed(); return(TaskEx.FromException(t)); } if (wasActive && !this.channel.Active) { this.InvokeLater(() => this.channel.pipeline.FireChannelInactive()); } this.CloseIfClosed(); // doDisconnect() might have closed the channel return(TaskEx.Completed); }
/// <summary> /// INTERNAL API /// /// Should only be called directly by the <see cref="AppDomain.ProcessExit"/> event /// in production. /// /// Safe to call multiple times, but hooks will only be run once. /// </summary> /// <returns>Returns a <see cref="Task"/> that will be completed once the process exits.</returns> private Task <Done> RunClrHooks() { if (_clrHooksStarted.CompareAndSet(false, true)) { Task.WhenAll(_clrShutdownTasks.Select(hook => { try { var t = hook(); return(t); } catch (Exception ex) { Log.Error(ex, "Error occurred while executing CLR shutdown hook"); return(TaskEx.FromException <Done>(ex)); } })).ContinueWith(tr => { if (tr.IsFaulted || tr.IsCanceled) { _hooksRunPromise.SetException(tr.Exception.Flatten()); } else { _hooksRunPromise.SetResult(Done.Instance); } }); } return(ClrShutdownTask); }
public static void TaskExGenericFromExceptionIsFaulted() { var exception = new Exception(); var task = TaskEx.FromException <bool>(exception); Assert.IsTrue(task.IsFaulted); }
public Task <IByteBuffer> GetResponseAsync() { if (_excecption != null) { return(TaskEx.FromException <IByteBuffer>(_excecption)); } return(Task.FromResult(_buffer)); }
public static void TaskExGenericFromExceptionRespectsException() { var exception = new Exception(); var task = TaskEx.FromException <bool>(exception); // ReSharper disable once PossibleNullReferenceException Assert.AreEqual(exception, task.Exception.InnerException); }
public override Task WriteAsync(IChannelHandlerContext context, object message) { if (!(message is IByteBuffer)) { return(TaskEx.FromException(new UnsupportedMessageTypeException(message, typeof(IByteBuffer)))); } return(this.pendingUnencryptedWrites.Add(message)); }
Task SafeExecuteOutboundAsync(Func <Task> task) { try { return(this.executor.SubmitAsync(task)); } catch (Exception cause) { return(TaskEx.FromException(cause)); } }
public override Task WriteAsync(IChannelHandlerContext context, object message) { Contract.Requires(context != null); IByteBuffer buffer = null; Task result; try { if (this.AcceptOutboundMessage(message)) { buffer = this.AllocateBuffer(context); var input = (T)message; try { this.Encode(context, input, buffer); } finally { ReferenceCountUtil.Release(input); } if (buffer.IsReadable()) { result = context.WriteAsync(buffer); } else { buffer.Release(); result = context.WriteAsync(Unpooled.Empty); } buffer = null; } else { return(context.WriteAsync(message)); } } catch (EncoderException e) { return(TaskEx.FromException(e)); } catch (Exception ex) { return(TaskEx.FromException(new EncoderException(ex))); } finally { buffer?.Release(); } return(result); }
Task SafeProcessOutboundMessageAsync(Func <object, object, Task> task, object state, object msg) { try { return(this.executor.SubmitAsync(task, state, msg)); } catch (Exception cause) { ReferenceCountUtil.Release(msg); return(TaskEx.FromException(cause)); } }
public Task RegisterAsync(IEventLoop eventLoop) { Contract.Requires(eventLoop != null); if (this._channel.Registered) { return(TaskEx.FromException(new InvalidOperationException("registered to an event loop already"))); } if (!this._channel.IsCompatible(eventLoop)) { return (TaskEx.FromException( new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name))); } // It's necessary to reuse the wrapped eventloop object. Otherwise the user will end up with multiple // objects that do not share a common state. if (this._channel._eventLoop == null) { this._channel._eventLoop = new PausableChannelEventLoop(this._channel, eventLoop); } else { this._channel._eventLoop.Unwrapped = eventLoop; } var promise = new TaskCompletionSource(); if (eventLoop.InEventLoop) { this.Register0(promise); } else { try { eventLoop.Execute(() => this.Register0(promise)); } catch (Exception ex) { Logger.Warning( "Force-closing a channel whose registration task was not accepted by an event loop: {0}; Cause: {1}", _channel, ex); CloseForcibly(); _channel._closeTask.TryComplete(); PromiseUtil.SafeSetFailure(promise, ex, Logger); } } return(promise.Task); }
public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { if (Local._state == State.Connected) { var cause = new AlreadyConnectedException(); Local.Pipeline.FireExceptionCaught(cause); return(TaskEx.FromException(cause)); } if (Local._connectPromise != null) { throw new ConnectionPendingException(); } Local._connectPromise = new TaskCompletionSource(); if (Local._state != State.Bound) { // Not bound yet and no LocalAddress specified. Get one if (localAddress == null) { localAddress = new LocalAddress(Local); } } if (localAddress != null) { try { Local.DoBind(localAddress); } catch (Exception ex) { PromiseUtil.SafeSetFailure(Local._connectPromise, ex, Logger); return(CloseAsync()); } } var boundChannel = LocalChannelRegistry.Get(remoteAddress); if (!(boundChannel is LocalServerChannel)) { var cause = new ChannelException("connection refused"); PromiseUtil.SafeSetFailure(Local._connectPromise, cause, Logger); return(CloseAsync()); } var serverChannel = boundChannel as LocalServerChannel; Local._peer = serverChannel.Serve(Local); return(TaskEx.Completed); }
/// <summary> /// Returns a <see cref="Task"/> that will be completed with the success or failure /// of the provided value after the specified duration. /// </summary> /// <typeparam name="T">The return type of task.</typeparam> /// <param name="duration">The duration to wait.</param> /// <param name="scheduler">The scheduler instance to use.</param> /// <param name="value">The task we're going to wrap.</param> /// <returns>a <see cref="Task"/> that will be completed with the success or failure /// of the provided value after the specified duration</returns> public static Task <T> After <T>(TimeSpan duration, IScheduler scheduler, Func <Task <T> > value) { if (duration < TimeSpan.MaxValue && duration.Ticks < 1) { // no need to schedule try { return(value()); } catch (Exception ex) { return(TaskEx.FromException <T>(ex)); } } var tcs = new TaskCompletionSource <T>(); scheduler.Advanced.ScheduleOnce(duration, () => { try { value().ContinueWith(tr => { try { if (tr.IsCanceled || tr.IsFaulted) { tcs.SetException(tr.Exception.InnerException); } else { tcs.SetResult(tr.Result); } } catch (AggregateException ex) { // in case the task faults tcs.SetException(ex.Flatten()); } }); } catch (Exception ex) { // in case the value() function faults tcs.SetException(ex); } }); return(tcs.Task); }
protected override Task ProcessAsync(IChannelHandlerContext context, PacketWithId packet) { TAckState message; if (this.TryDequeueMessage(packet, out message)) { return(this.processAckFunc(context, message)); } else if (this.abortOnOutOfOrderAck) { return(TaskEx.FromException(new ProtocolGatewayException(ErrorCode.InvalidPubAckOrder, "Client MUST send PUBACK packets in the order in which the corresponding PUBLISH packets were received"))); } return(TaskEx.Completed); }
public async Task SmokeTest() { Task t1 = TaskEx.FromException(new InvalidOperationException("the message")); Assert.True(t1.IsFaulted); InvalidOperationException e1 = await Assert.ThrowsAsync <InvalidOperationException>(() => t1); Assert.Equal("the message", e1.Message); Task <int> t2 = TaskEx.FromException <int>(new BadImageFormatException("there's a bad image")); Assert.True(t1.IsFaulted); BadImageFormatException e2 = await Assert.ThrowsAsync <BadImageFormatException>(() => t2); Assert.Equal("there's a bad image", e2.Message); }
public Task HandshakeAsync(IChannel channel, IHttpRequest req, HttpHeaders responseHeaders) { if (req is IFullHttpRequest request) { return(this.HandshakeAsync(channel, request, responseHeaders)); } if (Logger.DebugEnabled) { Logger.Debug("{} WebSocket version {} server handshake", channel, this.version); } IChannelPipeline p = channel.Pipeline; IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>(); if (ctx == null) { // this means the user use a HttpServerCodec ctx = p.Context <HttpServerCodec>(); if (ctx == null) { return(TaskEx.FromException(new InvalidOperationException("No HttpDecoder and no HttpServerCodec in the pipeline"))); } } // Add aggregator and ensure we feed the HttpRequest so it is aggregated. A limit o 8192 should be more then // enough for the websockets handshake payload. // // TODO: Make handshake work without HttpObjectAggregator at all. string aggregatorName = "httpAggregator"; p.AddAfter(ctx.Name, aggregatorName, new HttpObjectAggregator(8192)); var completion = new TaskCompletionSource(); p.AddAfter(aggregatorName, "handshaker", new Handshaker(this, channel, responseHeaders, completion)); try { ctx.FireChannelRead(ReferenceCountUtil.Retain(req)); } catch (Exception cause) { completion.TrySetException(cause); } return(completion.Task); }
public Task BindAsync(EndPoint localAddress) { this.AssertEventLoop(); // todo: cancellation support if (/*!promise.setUncancellable() || */ !this.channel.Open) { return(this.CreateClosedChannelExceptionTask()); } //// See: https://github.com/netty/netty/issues/576 //if (bool.TrueString.Equals(this.channel.Configuration.getOption(ChannelOption.SO_BROADCAST)) && // localAddress is IPEndPoint && // !((IPEndPoint)localAddress).Address.getAddress().isAnyLocalAddress() && // !Environment.OSVersion.Platform == PlatformID.Win32NT && !Environment.isRoot()) //{ // // Warn a user about the fact that a non-root user can't receive a // // broadcast packet on *nix if the socket is bound on non-wildcard address. // logger.Warn( // "A non-root user can't receive a broadcast packet if the socket " + // "is not bound to a wildcard address; binding to a non-wildcard " + // "address (" + localAddress + ") anyway as requested."); //} bool wasActive = this.channel.Active; try { this.channel.DoBind(localAddress); } catch (Exception t) { this.CloseIfClosed(); return(TaskEx.FromException(t)); } if (!wasActive && this.channel.Active) { this.InvokeLater(() => this.channel.pipeline.FireChannelActive()); } return(TaskEx.Completed); }
public void CoordinatedShutdown_must_continue_after_timeout_or_failure() { var phases = new Dictionary <string, Phase>() { { "a", EmptyPhase }, { "b", new Phase(ImmutableHashSet <string> .Empty.Add("a"), TimeSpan.FromMilliseconds(100), true) }, { "c", Phase("b", "a") } }; var co = new CoordinatedShutdown(ExtSys, phases); co.AddTask("a", "a1", () => { TestActor.Tell("A"); return(TaskEx.FromException <Done>(new Exception("boom"))); }); co.AddTask("a", "a2", () => { Task.Delay(TimeSpan.FromMilliseconds(100)).Wait(); TestActor.Tell("A"); return(TaskEx.Completed); }); co.AddTask("b", "b1", () => { TestActor.Tell("B"); return(new TaskCompletionSource <Done>().Task); // never completed }); co.AddTask("c", "c1", () => { TestActor.Tell("C"); return(TaskEx.Completed); }); co.Run(CoordinatedShutdown.UnknownReason.Instance).Wait(RemainingOrDefault); ExpectMsg("A"); ExpectMsg("A"); ExpectMsg("B"); ExpectMsg("C"); }
public Task WriteAsync(object msg) { this.AssertEventLoop(); ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; if (outboundBuffer == null) { // If the outboundBuffer is null we know the channel was closed and so // need to fail the future right away. If it is not null the handling of the rest // will be done input flush0() // See https://github.com/netty/netty/issues/2362 // release message now to prevent resource-leak ReferenceCountUtil.Release(msg); return(TaskEx.FromException(new ClosedChannelException())); } int size; try { msg = this.channel.FilterOutboundMessage(msg); size = this.channel.pipeline.EstimatorHandle.Size(msg); if (size < 0) { size = 0; } } catch (Exception t) { ReferenceCountUtil.Release(msg); return(TaskEx.FromException(t)); } var promise = new TaskCompletionSource(); outboundBuffer.AddMessage(msg, size, promise); return(promise.Task); }
public Task RegisterAsync(IEventLoop eventLoop) { Contract.Requires(eventLoop != null); if (this.channel.Registered) { return(TaskEx.FromException(new InvalidOperationException("registered to an event loop already"))); } if (!this.channel.IsCompatible(eventLoop)) { return(TaskEx.FromException(new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name))); } this.channel.eventLoop = eventLoop; var promise = new TaskCompletionSource(); if (eventLoop.InEventLoop) { this.Register0(promise); } else { try { eventLoop.Execute((u, p) => ((AbstractUnsafe)u).Register0((TaskCompletionSource)p), this, promise); } catch (Exception ex) { Logger.Warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", this.channel, ex); this.CloseForcibly(); this.channel.closeFuture.Complete(); Util.SafeSetFailure(promise, ex, Logger); } } return(promise.Task); }
public override Task WriteAsync(IChannelHandlerContext context, object message) { if (!(message is IHttpRequest)) { return(context.WriteAsync(message)); } if (this.upgradeRequested) { return(TaskEx.FromException(new InvalidOperationException("Attempting to write HTTP request with upgrade in progress"))); } this.upgradeRequested = true; this.SetUpgradeRequestHeaders(context, (IHttpRequest)message); // Continue writing the request. Task task = context.WriteAsync(message); // Notify that the upgrade request was issued. context.FireUserEventTriggered(UpgradeEvent.UpgradeIssued); // Now we wait for the next HTTP response to see if we switch protocols. return(task); }
/// <summary> /// This method must NEVER be called directly, but be executed as an /// extra task with a clean call stack instead. The reason for this /// is that this method calls {@link ChannelPipeline#fireChannelUnregistered()} /// directly, which might lead to an unfortunate nesting of independent inbound/outbound /// events. See the comments input {@link #invokeLater(Runnable)} for more details. /// </summary> public Task DeregisterAsync() { //if (!promise.setUncancellable()) //{ // return; //} if (!this.channel.registered) { return(TaskEx.Completed); } try { this.channel.DoDeregister(); } catch (Exception t) { Logger.Warn("Unexpected exception occurred while deregistering a channel.", t); return(TaskEx.FromException(t)); } finally { if (this.channel.registered) { this.channel.registered = false; this.channel.pipeline.FireChannelUnregistered(); } else { // Some transports like local and AIO does not allow the deregistration of // an open channel. Their doDeregister() calls close(). Consequently, // close() calls deregister() again - no need to fire channelUnregistered. } } return(TaskEx.Completed); }
public DefaultServerUnsafe(AbstractChannel channel) : base(channel) { this.err = TaskEx.FromException(new NotSupportedException()); }
protected Task CreateClosedChannelExceptionTask() => TaskEx.FromException(new ClosedChannelException());
public override Task WriteAsync(IChannelHandlerContext ctx, object msg) { Task result; ThreadLocalObjectList output = null; try { if (this.AcceptOutboundMessage(msg)) { output = ThreadLocalObjectList.NewInstance(); var cast = (T)msg; try { this.Encode(ctx, cast, output); } finally { ReferenceCountUtil.Release(cast); } if (output.Count == 0) { output.Return(); output = null; throw new EncoderException(this.GetType().Name + " must produce at least one message."); } } else { return(ctx.WriteAsync(msg)); } } catch (EncoderException e) { return(TaskEx.FromException(e)); } catch (Exception ex) { return(TaskEx.FromException(new EncoderException(ex))); // todo: we don't have a stack on EncoderException but it's present on inner exception. } finally { if (output != null) { int lastItemIndex = output.Count - 1; if (lastItemIndex == 0) { result = ctx.WriteAsync(output[0]); } else if (lastItemIndex > 0) { for (int i = 0; i < lastItemIndex; i++) { // we don't care about output from these messages as failure while sending one of these messages will fail all messages up to the last message - which will be observed by the caller in Task result. ctx.WriteAsync(output[i]); // todo: optimize: once IChannelHandlerContext allows, pass "not interested in task" flag } result = ctx.WriteAsync(output[lastItemIndex]); } else { // 0 items in output - must never get here result = null; } output.Return(); } else { // output was reset during exception handling - must never get here result = null; } } return(result); }
public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { return(TaskEx.FromException(new NotSupportedException())); }
static Task ComposeExceptionTask(Exception cause) => TaskEx.FromException(cause);
public sealed override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { // todo: handle cancellation AbstractSocketChannel ch = this.Channel; if (!ch.Open) { return(this.CreateClosedChannelExceptionTask()); } try { if (ch.connectPromise != null) { throw new InvalidOperationException("connection attempt already made"); } bool wasActive = this.channel.Active; if (ch.DoConnect(remoteAddress, localAddress)) { this.FulfillConnectPromise(wasActive); return(TaskEx.Completed); } else { ch.connectPromise = new TaskCompletionSource(remoteAddress); // Schedule connect timeout. TimeSpan connectTimeout = ch.Configuration.ConnectTimeout; if (connectTimeout > TimeSpan.Zero) { ch.connectCancellationTask = ch.EventLoop.Schedule( (c, a) => { // todo: make static / cache delegate?.. var self = (AbstractSocketChannel)c; // todo: call Socket.CancelConnectAsync(...) TaskCompletionSource promise = self.connectPromise; var cause = new ConnectTimeoutException("connection timed out: " + a.ToString()); if (promise != null && promise.TrySetException(cause)) { self.CloseAsync(); } }, this.channel, remoteAddress, connectTimeout); } ch.connectPromise.Task.ContinueWith( (t, s) => { var c = (AbstractSocketChannel)s; c.connectCancellationTask?.Cancel(); c.connectPromise = null; c.CloseAsync(); }, ch, TaskContinuationOptions.OnlyOnCanceled | TaskContinuationOptions.ExecuteSynchronously); return(ch.connectPromise.Task); } } catch (Exception ex) { this.CloseIfClosed(); return(TaskEx.FromException(this.AnnotateConnectException(ex, remoteAddress))); } }
protected Task CreateClosedChannelExceptionTask() { return(TaskEx.FromException(ClosedChannelException)); }