/// <summary>
        /// Attempts to obtain a connection to the provided <paramref name="validHost"/> and send the request with it.
        /// If no connection could be obtained for the provided host, then attempts to obtain a connection
        /// for the next host, following the query plan.
        /// </summary>
        /// <param name="validHost">First host to which the method tries to obtain a connection.</param>
        /// <returns></returns>
        private async Task SendToNextHostAsync(ValidHost validHost)
        {
            try
            {
                IConnection connection = null;
                while (connection == null)
                {
                    connection = await _parent.GetConnectionToValidHostAsync(validHost, _triedHosts).ConfigureAwait(false);

                    if (connection == null)
                    {
                        validHost = _parent.GetNextValidHost(_triedHosts);
                    }
                }

                _connection = connection;
                _host       = validHost.Host;
                Send(_request, validHost.Host, HandleResponse);
            }
            catch (Exception ex)
            {
                _host = validHost.Host;
                HandleResponse(RequestError.CreateClientError(ex, true), null, validHost.Host);
            }
        }
 /// <summary>
 /// Useful method to retry the execution safely. While <see cref="Start"/> throws exceptions,
 /// this method catches them and marks the <see cref="_parent"/> request as complete,
 /// making it suitable to be called in a fire and forget manner.
 /// </summary>
 private void RetryExecution(bool currentHostRetry, Host host)
 {
     try
     {
         Start(currentHostRetry);
     }
     catch (Exception ex)
     {
         //There was an Exception before sending (probably no host is available).
         //This will mark the Task as faulted.
         HandleResponse(RequestError.CreateClientError(ex, true), null, host);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Marks this operation as timed-out, callbacks with the exception
        /// and sets a handler when the response is received
        /// </summary>
        public bool MarkAsTimedOut(OperationTimedOutException ex, Action onReceive, long timestamp)
        {
            var previousState = Interlocked.CompareExchange(ref _state, StateTimedout, StateInit);

            if (previousState != StateInit)
            {
                return(false);
            }
            //When the data is received, invoke on receive callback
            var callback = Interlocked.Exchange(ref _callback, (_, __, ___) => onReceive());

            Thread.MemoryBarrier();

            _timeoutCallbackSet = true;
            Task.Factory.StartNew(() => callback(RequestError.CreateClientError(ex, false), null, timestamp), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
            return(true);
        }
Beispiel #4
0
 internal static RetryDecision GetRetryDecisionFromClientError(Exception ex, IExtendedRetryPolicy policy, IStatement statement, Configuration config, int retryCount)
 {
     return(RequestExecution.GetRetryDecisionWithReason(RequestError.CreateClientError(ex, false), policy, statement, config, retryCount).Decision);
 }