private async Task DispatchAsync <TOutgoing>( IConnection connection, MessageType type, Message request, TOutgoing payload, CancellationToken cancellationToken) where TOutgoing : class { InboundRequestContext requestContext; if (!_inboundRequestContexts.TryGetValue(request.RequestId, out requestContext)) { return; } var message = MessageUtilities.Create(request.RequestId, type, request.Method, payload); try { await connection.SendAsync(message, cancellationToken); } finally { RemoveInboundRequestContext(request.RequestId); } }
private async Task ProcessResponseAsync(IRequestHandler requestHandler, Message request, IResponseHandler responseHandler) { try { if (_logger.IsEnabled) { _logger.Write(new TaskLogMessage(_logger.Now, request.RequestId, request.Method, request.Type, TaskState.Executing)); } await requestHandler.HandleResponseAsync( _connection, request, responseHandler, _cancellationToken); } catch (OperationCanceledException) when(_cancellationToken.IsCancellationRequested) { var response = MessageUtilities.Create(request.RequestId, MessageType.Cancel, request.Method); await _connection.SendAsync(response, CancellationToken.None); } catch (Exception ex) { BeginFaultAsync(request, ex); } finally { if (_logger.IsEnabled) { _logger.Write(new TaskLogMessage(_logger.Now, request.RequestId, request.Method, request.Type, TaskState.Completed)); } } }
private async Task DispatchProgressAsync( IConnection connection, Message request, Progress progress, CancellationToken cancellationToken) { var message = MessageUtilities.Create(request.RequestId, MessageType.Progress, request.Method, progress); await DispatchWithExistingContextAsync(connection, message, cancellationToken); }
/// <summary> /// Handles a response for the outbound request. /// </summary> /// <param name="response">A response.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="response" /> is <c>null</c>.</exception> public override void HandleResponse(Message response) { if (response == null) { throw new ArgumentNullException(nameof(response)); } var payload = MessageUtilities.DeserializePayload <TResult>(response); _taskCompletionSource.TrySetResult(payload); }
/// <summary> /// Asynchronously handles responding to a request. /// </summary> /// <param name="connection">The connection.</param> /// <param name="request">A request message.</param> /// <param name="responseHandler">A response handler.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="connection" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="responseHandler" /> /// is <c>null</c>.</exception> public async Task HandleResponseAsync( IConnection connection, Message request, IResponseHandler responseHandler, CancellationToken cancellationToken) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (responseHandler == null) { throw new ArgumentNullException(nameof(responseHandler)); } cancellationToken.ThrowIfCancellationRequested(); var monitorRequest = MessageUtilities.DeserializePayload <MonitorNuGetProcessExitRequest>(request); Process process = null; try { process = _processes.GetOrAdd(monitorRequest.ProcessId, pid => Process.GetProcessById(pid)); } catch (Exception) { } MessageResponseCode responseCode; if (process == null) { responseCode = MessageResponseCode.NotFound; } else { process.Exited += OnProcessExited; process.EnableRaisingEvents = true; responseCode = MessageResponseCode.Success; } var response = new MonitorNuGetProcessExitResponse(responseCode); await responseHandler.SendResponseAsync(request, response, cancellationToken); }
/// <summary> /// Handles a fault response for the outbound request. /// </summary> /// <param name="fault">A fault response.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="fault" /> is <c>null</c>.</exception> public override void HandleFault(Message fault) { if (fault == null) { throw new ArgumentNullException(nameof(fault)); } var payload = MessageUtilities.DeserializePayload <Fault>(fault); throw new ProtocolException(payload.Message); }
private void HandleInboundFault(IConnection connection, Message fault) { if (fault == null) { throw new ArgumentNullException(nameof(fault)); } var payload = MessageUtilities.DeserializePayload <Fault>(fault); throw new ProtocolException(payload.Message); }
/// <summary> /// Creates a message. /// </summary> /// <typeparam name="TPayload">The message payload.</typeparam> /// <param name="type">The message type.</param> /// <param name="method">The message method.</param> /// <param name="payload">The message payload.</param> /// <returns>A message.</returns> /// <exception cref="ArgumentNullException">Throws if <paramref name="payload" /> is <c>null</c>.</exception> public Message CreateMessage <TPayload>(MessageType type, MessageMethod method, TPayload payload) where TPayload : class { if (payload == null) { throw new ArgumentNullException(nameof(payload)); } var requestId = _idGenerator.GenerateUniqueId(); return(MessageUtilities.Create(requestId, type, method, payload)); }
/// <summary> /// Asynchronously handles responding to a request. /// </summary> /// <param name="connection">The connection.</param> /// <param name="request">A request message.</param> /// <param name="responseHandler">A response handler.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="connection" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="responseHandler" /> /// is <c>null</c>.</exception> /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" /> /// is cancelled.</exception> public async Task HandleResponseAsync( IConnection connection, Message request, IResponseHandler responseHandler, CancellationToken cancellationToken) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (responseHandler == null) { throw new ArgumentNullException(nameof(responseHandler)); } cancellationToken.ThrowIfCancellationRequested(); var response = _handshakeFailedResponse; var handshakeRequest = MessageUtilities.DeserializePayload<HandshakeRequest>(request); if (handshakeRequest != null) { if (!(handshakeRequest.MinimumProtocolVersion > handshakeRequest.ProtocolVersion || handshakeRequest.ProtocolVersion < _minimumProtocolVersion || handshakeRequest.MinimumProtocolVersion > _protocolVersion)) { SemanticVersion negotiatedProtocolVersion; if (_protocolVersion <= handshakeRequest.ProtocolVersion) { negotiatedProtocolVersion = _protocolVersion; } else { negotiatedProtocolVersion = handshakeRequest.ProtocolVersion; } response = new HandshakeResponse(MessageResponseCode.Success, negotiatedProtocolVersion); } } await responseHandler.SendResponseAsync(request, response, cancellationToken) .ContinueWith(task => _responseSentTaskCompletionSource.TrySetResult(0)) .ConfigureAwait(false); }
/// <summary> /// Handles progress notifications for the outbound request. /// </summary> /// <param name="progress">A progress notification.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="progress" /> is <c>null</c>.</exception> public override void HandleProgress(Message progress) { if (progress == null) { throw new ArgumentNullException(nameof(progress)); } var payload = MessageUtilities.DeserializePayload <Progress>(progress); if (_timeout.HasValue && _isKeepAlive) { _timer.Change(_timeout.Value, Timeout.InfiniteTimeSpan); } }
private void OnTimer(object state) { try { _semaphore.Wait(_cancellationToken); } catch (OperationCanceledException) { return; } catch (ObjectDisposedException) { return; } catch (ArgumentNullException) { // The semaphore may have been disposed already. return; } if (_isDisposed) { return; } Task.Run(async() => { // Top-level exception handler for a worker pool thread. try { var progress = MessageUtilities.Create( _request.RequestId, MessageType.Progress, _request.Method, new Progress()); await _connection.SendAsync(progress, _cancellationToken).ConfigureAwait(false); } catch (Exception) { } finally { _semaphore.Release(); } }, _cancellationToken); }
/// <summary> /// Asynchronously handles responding to a request. /// </summary> /// <param name="connection">The connection.</param> /// <param name="request">A request message.</param> /// <param name="responseHandler">A response handler.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="connection" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="responseHandler" /> /// is <c>null</c>.</exception> /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" /> /// is cancelled.</exception> public async Task HandleResponseAsync( IConnection connection, Message request, IResponseHandler responseHandler, CancellationToken cancellationToken) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (responseHandler == null) { throw new ArgumentNullException(nameof(responseHandler)); } cancellationToken.ThrowIfCancellationRequested(); var getRequest = MessageUtilities.DeserializePayload <GetServiceIndexRequest>(request); SourceRepository sourceRepository; ServiceIndexResourceV3 serviceIndex = null; GetServiceIndexResponse responsePayload; if (_repositories.TryGetValue(getRequest.PackageSourceRepository, out sourceRepository)) { serviceIndex = await sourceRepository.GetResourceAsync <ServiceIndexResourceV3>(cancellationToken) .ConfigureAwait(false); } if (serviceIndex == null) { responsePayload = new GetServiceIndexResponse(MessageResponseCode.NotFound, serviceIndex: null); } else { var serviceIndexJson = JObject.Parse(serviceIndex.Json); responsePayload = new GetServiceIndexResponse(MessageResponseCode.Success, serviceIndexJson); } await responseHandler.SendResponseAsync(request, responsePayload, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Asynchronously starts processing a response for the inbound request. /// </summary> /// <param name="request">The request.</param> /// <param name="requestHandler">A request handler.</param> /// <param name="responseHandler">A response handler.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="requestHandler" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="responseHandler" /> /// is <c>null</c>.</exception> public void BeginResponseAsync( Message request, IRequestHandler requestHandler, IResponseHandler responseHandler) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (requestHandler == null) { throw new ArgumentNullException(nameof(requestHandler)); } if (responseHandler == null) { throw new ArgumentNullException(nameof(responseHandler)); } Task.Run(async() => { // Top-level exception handler for a worker pool thread. try { await requestHandler.HandleResponseAsync( _connection, request, responseHandler, _cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) when(_cancellationToken.IsCancellationRequested) { var response = MessageUtilities.Create(request.RequestId, MessageType.Cancel, request.Method); await _connection.SendAsync(response, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { BeginFaultAsync(request, ex); } }, _cancellationToken); }
/// <summary> /// Asynchronously handles responding to a request. /// </summary> /// <param name="connection">The connection.</param> /// <param name="request">A request message.</param> /// <param name="responseHandler">A response handler.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="connection" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="responseHandler" /> /// is <c>null</c>.</exception> /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" /> /// is cancelled.</exception> public async Task HandleResponseAsync( IConnection connection, Message request, IResponseHandler responseHandler, CancellationToken cancellationToken) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (responseHandler == null) { throw new ArgumentNullException(nameof(responseHandler)); } cancellationToken.ThrowIfCancellationRequested(); var logRequest = MessageUtilities.DeserializePayload <LogRequest>(request); MessageResponseCode responseCode; if (logRequest.LogLevel >= _logLevel) { Log(logRequest); responseCode = MessageResponseCode.Success; } else { responseCode = MessageResponseCode.Error; } var response = new LogResponse(responseCode); await responseHandler.SendResponseAsync(request, response, cancellationToken); }
/// <summary> /// Asynchronously starts processing a response for the inbound request. /// </summary> /// <param name="request">The request.</param> /// <param name="requestHandler">A request handler.</param> /// <param name="responseHandler">A response handler.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="requestHandler" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="responseHandler" /> /// is <c>null</c>.</exception> public void BeginResponseAsync( Message request, IRequestHandler requestHandler, IResponseHandler responseHandler) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (requestHandler == null) { throw new ArgumentNullException(nameof(requestHandler)); } if (responseHandler == null) { throw new ArgumentNullException(nameof(responseHandler)); } if (_logger.IsEnabled) { _logger.Write(new TaskLogMessage(_logger.Now, request.RequestId, request.Method, request.Type, TaskState.Queued)); } Task.Run(async() => { // Top-level exception handler for a worker pool thread. try { if (_logger.IsEnabled) { _logger.Write(new TaskLogMessage(_logger.Now, request.RequestId, request.Method, request.Type, TaskState.Executing)); } await requestHandler.HandleResponseAsync( _connection, request, responseHandler, _cancellationToken); } catch (OperationCanceledException) when(_cancellationToken.IsCancellationRequested) { var response = MessageUtilities.Create(request.RequestId, MessageType.Cancel, request.Method); await _connection.SendAsync(response, CancellationToken.None); } catch (Exception ex) { BeginFaultAsync(request, ex); } finally { if (_logger.IsEnabled) { _logger.Write(new TaskLogMessage(_logger.Now, request.RequestId, request.Method, request.Type, TaskState.Completed)); } } }, _cancellationToken); }
/// <summary> /// Creates a message. /// </summary> /// <param name="type">The message type.</param> /// <param name="method">The message method.</param> /// <returns>A message.</returns> public Message CreateMessage(MessageType type, MessageMethod method) { var requestId = _idGenerator.GenerateUniqueId(); return(MessageUtilities.Create(requestId, type, method)); }
/// <summary> /// Asynchronously handles responding to a request. /// </summary> /// <param name="connection">The connection.</param> /// <param name="request">A request message.</param> /// <param name="responseHandler">A response handler.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="connection" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="responseHandler" /> /// is <c>null</c>.</exception> /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" /> /// is cancelled.</exception> public async Task HandleResponseAsync( IConnection connection, Message request, IResponseHandler responseHandler, CancellationToken cancellationToken) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (responseHandler == null) { throw new ArgumentNullException(nameof(responseHandler)); } cancellationToken.ThrowIfCancellationRequested(); var requestPayload = MessageUtilities.DeserializePayload <GetCredentialsRequest>(request); var packageSource = GetPackageSource(requestPayload.PackageSourceRepository); GetCredentialsResponse responsePayload; if (packageSource.IsHttp && string.Equals( requestPayload.PackageSourceRepository, packageSource.Source, StringComparison.OrdinalIgnoreCase)) { NetworkCredential credential = null; using (var progressReporter = AutomaticProgressReporter.Create( _plugin.Connection, request, PluginConstants.ProgressInterval, cancellationToken)) { credential = await GetCredentialAsync( packageSource, requestPayload.StatusCode, cancellationToken); } if (credential == null) { responsePayload = new GetCredentialsResponse( MessageResponseCode.NotFound, username: null, password: null); } else { responsePayload = new GetCredentialsResponse( MessageResponseCode.Success, credential.UserName, credential.Password); } } else { responsePayload = new GetCredentialsResponse( MessageResponseCode.NotFound, username: null, password: null); } await responseHandler.SendResponseAsync(request, responsePayload, cancellationToken); }