protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request) { string packageName = ExtractPackageName(request.RequestUri); if (!String.IsNullOrEmpty(packageName)) { return(FetchPackage(packageName).Then(package => { if (package != null && package.d.results.Count > 0) { var packageInfo = package.d.results[0]; var projectIcon = String.Empty; if (packageInfo.IconUrl != null) { projectIcon = String.Format("<img class=\"nuget-projecticon\" src=\"{0}\" />", packageInfo.IconUrl); } var projectInfo = new StringBuilder(); projectInfo.AppendFormat("<div class=\"nuget-authors\" ><span>Authors: </span><div class=\"nuget-authors-entry\">{0}</div></div>", packageInfo.Authors); projectInfo.AppendFormat("<div class=\"nuget-downloads\" ><span># Downloads:</span> {0}</div>", packageInfo.DownloadCount); if (packageInfo.ProjectUrl != null) { projectInfo.AppendFormat( "<div class=\"nuget-ProjectUrl\" ><a target=\"_blank\" href=\"{0}\">{0}</a></div>", packageInfo.ProjectUrl); } return new ContentProviderResult() { Content = String.Format(_nugetBadgeFormat, packageInfo.Id, packageInfo.Title, packageInfo.Summary, projectIcon, packageInfo.Description, projectInfo), Title = packageInfo.Title + " NuGet package" }; } return null; })); } return(TaskAsyncHelper.FromResult <ContentProviderResult>(null)); }
private void Reconnect(IConnection connection, string data) { if (CancellationToken.IsCancellationRequested) { return; } // Wait for a bit before reconnecting TaskAsyncHelper.Delay(ReconnectDelay).Then(() => { // Now attempt a reconnect OpenConnection(connection, data, initializeCallback: null, errorCallback: null); }); }
public override async System.Threading.Tasks.Task <object> ExecuteInsertAsync <T>(Database db, DbCommand cmd, string primaryKeyName, bool useOutputClause, T poco, object[] args) { if (primaryKeyName != null) { var param = AdjustSqlInsertCommandText(cmd, primaryKeyName); await db.ExecuteNonQueryHelperAsync(cmd); return(param.Value); } await db.ExecuteNonQueryHelperAsync(cmd); return(TaskAsyncHelper.FromResult <object>(-1)); }
public void FailedWriteCompletesRequestAfterDisconnectTimeout() { var request = new Mock <IRequest>(); var response = new Mock <IResponse>(); var qs = new NameValueCollection(); request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs)); var url = new Uri("http://test/echo/connect"); request.Setup(m => m.Url).Returns(url); request.Setup(m => m.LocalPath).Returns(url.LocalPath); var cts = new CancellationTokenSource(); response.Setup(m => m.CancellationToken).Returns(cts.Token); response.Setup(m => m.Flush()).Returns(TaskAsyncHelper.Empty); var resolver = new DefaultDependencyResolver(); var config = resolver.Resolve <IConfigurationManager>(); var hostContext = new HostContext(request.Object, response.Object); config.DisconnectTimeout = TimeSpan.FromSeconds(6); var transport = new Mock <ForeverTransport>(hostContext, resolver) { CallBase = true }; transport.Object.ConnectionId = "1"; transport.Setup(m => m.Send(It.IsAny <PersistentResponse>())) .Returns(() => { var task = TaskAsyncHelper.FromError(new Exception()); cts.Cancel(); return(task); }); var connectionManager = new ConnectionManager(resolver); var connection = connectionManager.GetConnectionCore("Foo"); var wh = new ManualResetEventSlim(); transport.Object.ProcessRequest(connection).ContinueWith(task => { wh.Set(); }); connection.Broadcast("Some message"); // 6 second disconnect timeout + 5 second disconnect threshold // + up to 1 second for the heartbeat to check + 3 second leeway Assert.True(wh.Wait(TimeSpan.FromSeconds(15))); }
private void Reconnect(IConnection connection, string data, CancellationToken disconnectToken) { // Wait for a bit before reconnecting TaskAsyncHelper.Delay(ReconnectDelay).Then(() => { // FIX: Race if Connection is stopped and completely restarted between checking the token and calling // connection.EnsureReconnecting() if (!disconnectToken.IsCancellationRequested && connection.EnsureReconnecting()) { // Now attempt a reconnect OpenConnection(connection, data, disconnectToken, initializeCallback: null, errorCallback: null); } }); }
public virtual Func <IHubIncomingInvokerContext, Task <object> > BuildIncoming(Func <IHubIncomingInvokerContext, Task <object> > invoke) { return(context => { if (OnBeforeIncoming(context)) { return invoke(context).OrEmpty() .Then(result => OnAfterIncoming(result, context)) .Catch(ex => OnIncomingError(ex, context)); } return TaskAsyncHelper.FromResult <object>(null); }); }
private bool ContinueReceiving(IAsyncResult asyncResult, ReceiverContext receiverContext) { bool shouldContinue = true; TimeSpan backoffAmount = BackoffAmount; try { IEnumerable <BrokeredMessage> messages = receiverContext.Receiver.EndReceiveBatch(asyncResult); receiverContext.OnMessage(messages); // Reset the receive timeout if it changed receiverContext.ReceiveTimeout = DefaultReadTimeout; } catch (ServerBusyException ex) { receiverContext.OnError(ex); // Too busy so back off shouldContinue = false; } catch (OperationCanceledException) { // This means the channel is closed return(false); } catch (Exception ex) { receiverContext.OnError(ex); shouldContinue = false; // TODO: Exponential backoff backoffAmount = ErrorBackOffAmount; // After an error, we want to adjust the timeout so that we // can recover as quickly as possible even if there's no message receiverContext.ReceiveTimeout = ErrorReadTimeout; } if (!shouldContinue) { TaskAsyncHelper.Delay(backoffAmount) .Then(ctx => ProcessMessages(ctx), receiverContext); return(false); } return(true); }
protected Task ProcessRequestCore(ITransportConnection connection) { Connection = connection; if (Context.Request.Url.LocalPath.EndsWith("/send", StringComparison.OrdinalIgnoreCase)) { return(ProcessSendRequest()); } else if (IsAbortRequest) { return(Connection.Abort(ConnectionId)); } else { InitializePersistentState(); if (IsConnectRequest) { if (Connected != null) { // Return a task that completes when the connected event task & the receive loop task are both finished bool newConnection = Heartbeat.AddConnection(this); // The connected callback Func <Task> connected = () => { if (newConnection) { return(Connected().Then(() => _counters.ConnectionsConnected.Increment())); } return(TaskAsyncHelper.Empty); }; return(TaskAsyncHelper.Interleave(ProcessReceiveRequestWithoutTracking, connected, connection, Completed)); } return(ProcessReceiveRequest(connection)); } if (Reconnected != null) { // Return a task that completes when the reconnected event task & the receive loop task are both finished Func <Task> reconnected = () => Reconnected().Then(() => _counters.ConnectionsReconnected.Increment()); return(TaskAsyncHelper.Interleave(ProcessReceiveRequest, reconnected, connection, Completed)); } return(ProcessReceiveRequest(connection)); } }
public Task ProcessRequest(IReceivingConnection connection) { // This will only be called on the first request so we return a task that fires on connect var taskCompletionSource = new TaskCompletionSource <object>(); _webSocketConnection.OnOpen = () => { if (Connected != null) { TaskAsyncHelper.Interleave(ProcessMessages, Connected, connection).ContinueWith(taskCompletionSource); } else { // Just process messages if there's no handler ProcessMessages(connection).ContinueWith(taskCompletionSource); } }; _webSocketConnection.OnClose = () => { _disconnected = true; if (Disconnected != null) { Disconnected().Catch(); } }; _webSocketConnection.OnError = ex => { _disconnected = true; if (Error != null) { Error(ex).Catch(); } }; _webSocketConnection.OnMessage = data => { if (Received != null) { Received(data).Catch(); } }; return(taskCompletionSource.Task); }
private Task ProcessRequestAsync(HttpListenerContext context) { try { Debug.WriteLine("Server: Incoming request to {0}.", context.Request.Url); PersistentConnection connection; string path = ResolvePath(context.Request.Url); if (TryGetConnection(path, out connection)) { var cts = new CancellationTokenSource(); // https://developer.mozilla.org/En/HTTP_Access_Control string origin = context.Request.Headers["Origin"]; if (!String.IsNullOrEmpty(origin)) { context.Response.AddHeader("Access-Control-Allow-Origin", origin); context.Response.AddHeader("Access-Control-Allow-Credentials", "true"); } var request = new HttpListenerRequestWrapper(context.Request, context.User); var response = new HttpListenerResponseWrapper(context.Response, () => RegisterForDisconnect(context, cts.Cancel), cts.Token); var hostContext = new HostContext(request, response); if (OnProcessRequest != null) { OnProcessRequest(hostContext); } #if DEBUG hostContext.Items[HostConstants.DebugMode] = true; #endif hostContext.Items["System.Net.HttpListenerContext"] = context; // Initialize the connection connection.Initialize(DependencyResolver); return(connection.ProcessRequestAsync(hostContext)); } return(context.Response.NotFound()); } catch (Exception ex) { return(TaskAsyncHelper.FromError(ex)); } }
public TransportInitializationHandler(IHttpClient httpClient, IConnection connection, string connectionData, string transport, CancellationToken disconnectToken, TransportHelper transportHelper) { if (connection == null) { throw new ArgumentNullException("connection"); } _connection = connection; _httpClient = httpClient; _connectionData = connectionData; _transport = transport; _transportHelper = transportHelper; _initializationTask = new DispatchingTaskCompletionSource <object>(); _initializationInvoker = new ThreadSafeInvoker(); // Default event OnFailure = () => { }; // We want to fail if the disconnect token is tripped while we're waiting on initialization try { _tokenCleanup = disconnectToken.SafeRegister( _ => Fail(new OperationCanceledException(Resources.Error_ConnectionCancelled, disconnectToken)), state: null); } catch (ObjectDisposedException) { // We only dispose this token after cancelling it, so consider this cancellation. // The ODE is only thrown on .NET 4.5.2 and below (.NET 4.6 no longer throws ODE from CTS.Register) Fail(new OperationCanceledException(Resources.Error_ConnectionCancelled, disconnectToken)); } TaskAsyncHelper.Delay(connection.TotalTransportConnectTimeout) .Then(() => { // don't timeout once connect request has finished if (Interlocked.CompareExchange(ref _state, InitializationState.Failed, InitializationState.Initial) == InitializationState.Initial) { Fail(new TimeoutException(Resources.Error_TransportTimedOutTryingToConnect)); } }); }
public void UncleanDisconnectFiresOnDisconnected() { // Arrange var context = new TestContext("/", new Dictionary <string, string> { { "connectionToken", "1" } }); var transport = new Mock <ITransport>(); transport.SetupProperty(m => m.Disconnected); transport.SetupProperty(m => m.ConnectionId); transport.Setup(m => m.GetGroupsToken()).Returns(TaskAsyncHelper.FromResult(string.Empty)); transport.Setup(m => m.ProcessRequest(It.IsAny <Connection>())).Returns(TaskAsyncHelper.Empty); var transportManager = new Mock <ITransportManager>(); transportManager.Setup(m => m.GetTransport(context.MockHttpContext.Object)).Returns(transport.Object); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); var connection = new Mock <PersistentConnection>() { CallBase = true }; var onDisconnectedCalled = false; connection.Protected().Setup("OnDisconnected", context.MockRequest.Object, "1", false).Callback(() => { onDisconnectedCalled = true; }); var sp = ServiceProviderHelper.CreateServiceProvider(services => { services.AddInstance <ITransportManager>(transportManager.Object); services.AddInstance <IProtectedData>(protectedData.Object); }); connection.Object.Initialize(sp); // Act connection.Object.ProcessRequest(context.MockHttpContext.Object).Wait(); transport.Object.Disconnected(/* clean: */ false); // Assert Assert.True(onDisconnectedCalled); }
public Task AcceptWebSocketRequest(Func <IWebSocket, Task> callback) { var accept = Get <Action <IDictionary <string, object>, WebSocketFunc> >(OwinConstants.WebSocketAccept); if (accept == null) { return(TaskAsyncHelper.FromError(new InvalidOperationException("Not a web socket request"))); } var options = new Dictionary <string, object>(); var worker = new ServerRequestWebSocket(callback); accept(options, worker.Invoke); return(TaskAsyncHelper.Empty); }
public void Test_SetUnwrappedException_with_aggregate_exception_sets_inner_exception() { // Arrange var subEx1 = new ArgumentNullException("foo"); var subEx2 = new InvalidOperationException("bar"); var ex = new AggregateException(subEx1, subEx2); // Act var task = TaskAsyncHelper.FromError(ex); // Assert Assert.That(task.Exception.InnerExceptions.Count, Is.EqualTo(2)); Assert.That(task.Exception.InnerExceptions, Contains.Item(subEx1)); Assert.That(task.Exception.InnerExceptions, Contains.Item(subEx2)); }
public void FailedNegotiateShouldBeDisconnected() { var connection = new Client.Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection, It.IsAny <string>())) .Returns(TaskAsyncHelper.FromError <NegotiationResponse>(new InvalidOperationException("Something failed."))); var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(InvalidOperationException), ex); Assert.Equal("Something failed.", ex.Message); Assert.Equal(ConnectionState.Disconnected, connection.State); }
protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request) { var args = ExtractParameters(request.RequestUri); if (args == null || !args.Any()) { return(TaskAsyncHelper.FromResult <ContentProviderResult>(null)); } return(TaskAsyncHelper.FromResult(new ContentProviderResult() { Content = String.Format(MediaFormatString, args.ToArray()), Title = request.RequestUri.AbsoluteUri.ToString() })); }
public static Task WriteAsync(this Stream stream, byte[] buffer) { #if NETFX_CORE return(stream.WriteAsync(buffer, 0, buffer.Length)); #else try { return(Task.Factory.FromAsync((cb, state) => stream.BeginWrite(buffer, 0, buffer.Length, cb, state), ar => stream.EndWrite(ar), null)); } catch (Exception ex) { return(TaskAsyncHelper.FromError(ex)); } #endif }
public void FailsIfProtocolVersionIsNull() { var connection = new Connection("http://test"); var transport = new Mock <IClientTransport>(); transport.Setup(m => m.Negotiate(connection)).Returns(TaskAsyncHelper.FromResult(new NegotiationResponse { ProtocolVersion = null })); var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait()); var ex = aggEx.Unwrap(); Assert.IsType(typeof(InvalidOperationException), ex); Assert.Equal("Incompatible protocol version.", ex.Message); }
protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request) { string id = request.RequestUri.AbsoluteUri.Split('/').Last(); string format = @"<img src=""https://i.imgur.com/{0}.jpg"" />"; if (_config.ProxyImages) { format = @"<img src=""proxy?url=http://i.imgur.com/{0}.jpg"" />"; } return(TaskAsyncHelper.FromResult(new ContentProviderResult() { Content = String.Format(format, id), Title = request.RequestUri.AbsoluteUri })); }
public static Task <int> ExecuteNonQueryAsync(this IDbCommand command) { var sqlCommand = command as SqlCommand; if (sqlCommand != null) { return(Task.Factory.FromAsync( (cb, state) => sqlCommand.BeginExecuteNonQuery(cb, state), iar => sqlCommand.EndExecuteNonQuery(iar), null)); } else { return(TaskAsyncHelper.FromResult(command.ExecuteNonQuery())); } }
protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request) { var match = TwitPicUrlRegex.Match(request.RequestUri.AbsoluteUri); if (match.Success) { var id = match.Groups["Id"].Value; return(TaskAsyncHelper.FromResult(new ContentProviderResult() { Content = String.Format(_twitPicFormatString, id), Title = request.RequestUri.AbsoluteUri })); } return(TaskAsyncHelper.FromResult <ContentProviderResult>(null)); }
public void FailedWriteCompletesRequestAfterDisconnectTimeout() { var request = new Mock <IRequest>(); var response = new Mock <IResponse>(); var qs = new NameValueCollection(); qs["connectionId"] = "1"; request.Setup(m => m.QueryString).Returns(qs); request.Setup(m => m.Url).Returns(new Uri("http://test/echo/connect")); response.Setup(m => m.EndAsync()).Returns(TaskAsyncHelper.Empty); bool isConnected = true; response.Setup(m => m.IsClientConnected).Returns(() => isConnected); response.Setup(m => m.FlushAsync()).Returns(TaskAsyncHelper.Empty); var resolver = new DefaultDependencyResolver(); var config = resolver.Resolve <IConfigurationManager>(); var hostContext = new HostContext(request.Object, response.Object); config.DisconnectTimeout = TimeSpan.Zero; config.HeartbeatInterval = TimeSpan.FromSeconds(3); var transport = new Mock <ForeverTransport>(hostContext, resolver) { CallBase = true }; transport.Setup(m => m.Send(It.IsAny <PersistentResponse>())) .Returns(() => { var task = TaskAsyncHelper.FromError(new Exception()); isConnected = false; return(task); }); var connectionManager = new ConnectionManager(resolver); var connection = connectionManager.GetConnection("Foo"); var wh = new ManualResetEventSlim(); transport.Object.ProcessRequest(connection).ContinueWith(task => { wh.Set(); }); connection.Broadcast("Some message"); Assert.True(wh.Wait(TimeSpan.FromSeconds(10))); }
public Task <IResponse> Post(string url, Action <Client.Http.IRequest> prepareRequest, IDictionary <string, string> postData) { var response = new Mock <IResponse>(); var request = new Mock <Client.Http.IRequest>(); var mockStream = new MemoryStream(); var sw = new StreamWriter(mockStream); sw.Write("{}"); sw.Flush(); mockStream.Position = 0; response.Setup(r => r.GetStream()).Returns(mockStream); prepareRequest(request.Object); return(TaskAsyncHelper.FromResult <IResponse>(response.Object)); }
public Task AcceptWebSocketRequest(Func <IWebSocket, Task> callback) { #if NET45 var accept = _environment.Get <Action <IDictionary <string, object>, WebSocketFunc> >(OwinConstants.WebSocketAccept); if (accept == null) { return(TaskAsyncHelper.FromError(new InvalidOperationException("Not a web socket request"))); } var options = new Dictionary <string, object>(); var handler = new OwinWebSocketHandler(callback); accept(options, handler.ProcessRequestAsync); return(TaskAsyncHelper.Empty); #else throw new NotImplementedException(); #endif }
public void InvokeWithErrorInHubResultReturnsFaultedTask() { var result = new HubResult <object> { Error = "This in an error" }; var connection = new Mock <SignalR.Client.IConnection>(); connection.Setup(m => m.Send <HubResult <object> >(It.IsAny <string>())) .Returns(TaskAsyncHelper.FromResult(result)); var hubProxy = new HubProxy(connection.Object, "foo"); AssertAggregateException(() => hubProxy.Invoke("Invoke").Wait(), "This in an error"); }
public static Task WriteAsync(this HttpListenerResponse response, ArraySegment <byte> buffer) { #if NET45 return(response.OutputStream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count)); #else try { return(Task.Factory.FromAsync((cb, state) => response.OutputStream.BeginWrite(buffer.Array, buffer.Offset, buffer.Count, cb, state), ar => response.OutputStream.EndWrite(ar), null)); } catch (Exception ex) { return(TaskAsyncHelper.FromError(ex)); } #endif }
public Task <IClientResponse> ProcessRequest(string url, Action <IClientRequest> prepareRequest, Dictionary <string, string> postData, bool disableWrites = false) { var uri = new Uri(url); PersistentConnection connection; if (!_shutDownToken.IsCancellationRequested && TryGetConnection(uri.LocalPath, out connection)) { var tcs = new TaskCompletionSource <IClientResponse>(); var clientTokenSource = new CancellationTokenSource(); var request = new Request(uri, clientTokenSource, postData, User); prepareRequest(request); Response response = null; response = new Response(clientTokenSource.Token, () => tcs.TrySetResult(response)) { DisableWrites = disableWrites }; var hostContext = new HostContext(request, response); hostContext.Items[HostConstants.ShutdownToken] = _shutDownToken.Token; connection.Initialize(DependencyResolver, hostContext); connection.ProcessRequestAsync(hostContext).ContinueWith(task => { if (task.IsFaulted) { tcs.TrySetException(task.Exception); } else if (task.IsCanceled) { tcs.TrySetCanceled(); } else { tcs.TrySetResult(response); } response.Close(); }); return(tcs.Task); } return(TaskAsyncHelper.FromError <IClientResponse>(new InvalidOperationException("Not a valid end point"))); }
private Task ProcessReceiveRequest(ITransportConnection connection) { Func <Task> initialize = null; // If this transport isn't replacing an existing transport, oldConnection will be null. ITrackingConnection oldConnection = Heartbeat.AddOrUpdateConnection(this); bool newConnection = oldConnection == null; if (IsConnectRequest) { Func <Task> connected; if (newConnection) { connected = Connected ?? _emptyTaskFunc; _counters.ConnectionsConnected.Increment(); } else { // Wait until the previous call to Connected completes. // We don't want to call Connected twice connected = () => oldConnection.ConnectTask; } initialize = () => { return(connected().Then((conn, id) => conn.Initialize(id), connection, ConnectionId)); }; } else { initialize = Reconnected; } var series = new Func <object, Task>[] { state => ((Func <Task>)state).Invoke(), state => ((Func <Task>)state).Invoke() }; var states = new object[] { TransportConnected ?? _emptyTaskFunc, initialize ?? _emptyTaskFunc }; Func <Task> fullInit = () => TaskAsyncHelper.Series(series, states).ContinueWith(_connectTcs); return(ProcessMessages(connection, fullInit)); }
private Task ConnectToRedis() { if (_connection != null) { _connection.Closed -= OnConnectionClosed; _connection.Error -= OnConnectionError; _connection.Dispose(); _connection = null; } // Create a new connection to redis with the factory RedisConnection connection = _connectionFactory(); connection.Closed += OnConnectionClosed; connection.Error += OnConnectionError; try { _trace.TraceInformation("Connecting..."); // Start the connection return(connection.Open().Then(() => { _trace.TraceInformation("Connection opened"); // Create a subscription channel in redis RedisSubscriberConnection channel = connection.GetOpenSubscriberChannel(); channel.CompletionMode = ResultCompletionMode.PreserveOrder; // Subscribe to the registered connections return channel.Subscribe(_key, OnMessage).Then(() => { _trace.TraceVerbose("Subscribed to event " + _key); _channel = channel; _connection = connection; }); })); } catch (Exception ex) { _trace.TraceError("Error connecting to Redis - " + ex.GetBaseException()); return(TaskAsyncHelper.FromError(ex)); } }
public override Task Send(IConnection connection, string data, string connectionData) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(); EventHandler <ErrorEventArgs> onError = null; Action <bool> onSent = null; // If we don't throw here when the WebSocket isn't open, WebSocketHander.SendAsync will noop. if (_webSocket.ReadyState != WebSocketState.Open) { // Make this a faulted task and trigger the OnError even to maintain consistency with the HttpBasedTransports var ex = new InvalidOperationException("Data can not be sent during WebSocket reconnect."); var result = TaskAsyncHelper.FromError(ex); connection.OnError(ex); return(result); } onError = (o, args) => { _webSocket.OnError -= onError; tcs.SetException(args.ToException()); }; onSent = (sent) => { _webSocket.OnError -= onError; if (sent) { tcs.SetResult(null); } // onError handler is invoked, when sent == false }; _webSocket.OnError += onError; _webSocket.SendAsync(data, onSent); return(tcs.Task); }