/// <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); } }
/// <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); }
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); }