private async Task <IClientChannel> GetChannelAsync(CancellationToken cancellationToken, string operationName) { var channelCreated = false; var clientChannel = _clientChannel; while (ShouldCreateChannel(clientChannel)) { cancellationToken.ThrowIfCancellationRequested(); await _semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { clientChannel = _clientChannel; if (ShouldCreateChannel(clientChannel)) { _cts?.Cancel(); _cts?.Dispose(); clientChannel = _clientChannel = await _builder .BuildAndEstablishAsync(cancellationToken) .ConfigureAwait(false); _cts = new CancellationTokenSource(); _finishedSessionTask = clientChannel.ReceiveFinishedSessionAsync(_cts.Token); channelCreated = true; break; } } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { throw; } catch (Exception ex) { var failedChannelInformation = new FailedChannelInformation( null, SessionState.New, null, null, false, ex, operationName); var handlers = ChannelCreationFailedHandlers.ToList(); if (!await InvokeHandlersAsync(handlers, failedChannelInformation, cancellationToken).ConfigureAwait(false)) { throw; } } finally { _semaphore.Release(); } } if (channelCreated && clientChannel != null) { var channelInformation = new ChannelInformation(clientChannel.SessionId, clientChannel.State, clientChannel.LocalNode, clientChannel.RemoteNode); var handlers = ChannelCreatedHandlers.ToList(); await InvokeHandlersAsync(handlers, channelInformation, cancellationToken).ConfigureAwait(false); } return(clientChannel); }
private Task <bool> ChannelOperationFailedAsync(FailedChannelInformation failedChannelInformation) { Trace.TraceError("Channel '{0}' operation failed: {1}", failedChannelInformation.SessionId, failedChannelInformation.Exception); if (_isDisconnecting) { return(TaskUtil.FalseCompletedTask); } return(TaskUtil.TrueCompletedTask); }
private async Task <bool> ChannelCreationFailedAsync(FailedChannelInformation failedChannelInformation) { Trace.TraceError("Channel '{0}' operation failed: {1}", failedChannelInformation.SessionId, failedChannelInformation.Exception); if (failedChannelInformation.Exception is LimeException ex && ex.Reason.Code == ReasonCodes.SESSION_AUTHENTICATION_FAILED) { return(false); } await Task.Delay(ChannelDiscardedDelay).ConfigureAwait(false); return(!_isDisconnecting); }
private Task <bool> ChannelOperationFailedAsync(FailedChannelInformation failedChannelInformation) { _logger.Error(failedChannelInformation.Exception, "Channel '{SessionId}' operation '{OperationName}' failed - Local node: {LocalNode} - Remote node: {RemoteNode}", failedChannelInformation.SessionId, failedChannelInformation.OperationName, failedChannelInformation.LocalNode, failedChannelInformation.RemoteNode); if (_isStopping) { return(TaskUtil.FalseCompletedTask); } return(TaskUtil.TrueCompletedTask); }
private async Task <bool> ChannelCreationFailedAsync(FailedChannelInformation failedChannelInformation) { _logger.Error(failedChannelInformation.Exception, "Channel '{SessionId}' creation failed - Local node: {LocalNode} - Remote node: {RemoteNode}", failedChannelInformation.SessionId, failedChannelInformation.LocalNode, failedChannelInformation.RemoteNode); if (failedChannelInformation.Exception is LimeException ex && ex.Reason.Code == ReasonCodes.SESSION_AUTHENTICATION_FAILED) { return(false); } await Task.Delay(ChannelDiscardedDelay).ConfigureAwait(false); return(!_isStopping); }
private async Task <bool> HandleChannelOperationExceptionAsync(Exception ex, string operationName, IChannel channel, CancellationToken cancellationToken) { try { var failedChannelInformation = new FailedChannelInformation( channel.SessionId, channel.State, channel.LocalNode, channel.RemoteNode, channel.Transport.IsConnected, ex, operationName); // Make a copy of the handlers var handlers = ChannelOperationFailedHandlers.ToList(); return(await InvokeHandlersAsync(handlers, failedChannelInformation, cancellationToken).ConfigureAwait(false)); } finally { await DiscardChannelAsync(channel, cancellationToken).ConfigureAwait(false); } }
private static async Task <bool> InvokeHandlersAsync(IEnumerable <Func <FailedChannelInformation, Task <bool> > > handlers, FailedChannelInformation failedChannelInformation, CancellationToken cancellationToken) { var exceptions = new List <Exception>(); var handled = true; foreach (var handler in handlers) { cancellationToken.ThrowIfCancellationRequested(); try { if (!await handler(failedChannelInformation).ConfigureAwait(false)) { handled = false; } } catch (Exception ex) { exceptions.Add(ex); } } ThrowIfAny(exceptions); return(handled); }