/// <summary> /// Sends the prepare request to all nodes have have an existing open connection. Will not attempt to send the request to hosts that were tried before (successfully or not). /// </summary> /// <param name="session"></param> /// <param name="request"></param> /// <param name="prepareResult">The result of the prepare request on the first node.</param> /// <returns></returns> private async Task SendRequestToAllNodesWithExistingConnections(IInternalSession session, InternalPrepareRequest request, PrepareResult prepareResult) { var pools = session.GetPools().ToDictionary(kvp => kvp.Key, kvp => kvp.Value); if (pools.Count == 0) { PrepareHandler.Logger.Warning("Could not prepare query on all hosts because there are no connection pools."); return; } using (var semaphore = new SemaphoreSlim(64, 64)) { var tasks = new List <Task>(pools.Count); foreach (var poolKvp in pools) { if (poolKvp.Key.Equals(prepareResult.HostAddress)) { continue; } if (prepareResult.TriedHosts.ContainsKey(poolKvp.Key)) { PrepareHandler.Logger.Warning( $"An error occured while attempting to prepare query on {{0}}:{Environment.NewLine}{{1}}", poolKvp.Key, prepareResult.TriedHosts[poolKvp.Key]); continue; } await semaphore.WaitAsync().ConfigureAwait(false); tasks.Add(SendSingleRequest(poolKvp, request, semaphore)); } await Task.WhenAll(tasks).ConfigureAwait(false); } }
private async Task <PrepareResult> SendRequestToOneNode(IInternalSession session, IEnumerator <Host> queryPlan, InternalPrepareRequest request) { var triedHosts = new Dictionary <IPEndPoint, Exception>(); while (true) { // It may throw a NoHostAvailableException which we should yield to the caller var connection = await GetNextConnection(session, queryPlan, triedHosts).ConfigureAwait(false); try { var result = await connection.Send(request).ConfigureAwait(false); return(new PrepareResult { PreparedStatement = await GetPreparedStatement(result, request, connection.Keyspace, session.Cluster).ConfigureAwait(false), TriedHosts = triedHosts, HostAddress = connection.Address }); } catch (Exception ex) when(PrepareHandler.CanBeRetried(ex)) { triedHosts[connection.Address] = ex; } } }