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);
        }
Пример #2
0
 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);
 }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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);
        }