/// <summary> /// Tries to create a connection to any of the contact points and retrieve cluster metadata for the first time. Not thread-safe. /// </summary> /// <exception cref="NoHostAvailableException" /> /// <exception cref="TimeoutException" /> /// <exception cref="DriverInternalError" /> internal async Task Init() { _logger.Info("Trying to connect the ControlConnection"); await Connect(true).ConfigureAwait(false); SubscribeEventHandlers(); var obtainingMetadataFailed = false; try { await RefreshNodeList().ConfigureAwait(false); await _metadata.RefreshKeyspaces(false).ConfigureAwait(false); } catch (SocketException ex) { _logger.Error("An error occurred when trying to retrieve the cluster metadata, retrying.", ex); // Can't be awaited on catch obtainingMetadataFailed = true; } if (obtainingMetadataFailed) { // There was a problem using the connection obtained, it is not usual but can happen // Retry one more time and throw if there is problem await Reconnect().ConfigureAwait(false); } }
internal void Refresh(bool reconnect = false, bool throwExceptions = false) { lock (_refreshLock) { try { if (reconnect) { Unsubscribe(); Connect(false); SubscribeEventHandlers(); } RefreshNodeList(); Metadata.RefreshKeyspaces(false); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); } catch (Exception ex) { _logger.Error("There was an error when trying to refresh the ControlConnection", ex); _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite); if (throwExceptions) { throw; } } } }
internal void Refresh() { if (Interlocked.Increment(ref _refreshCounter) != 1) { //Only one refresh at a time Interlocked.Decrement(ref _refreshCounter); return; } var reconnect = false; try { RefreshNodeList(); Metadata.RefreshKeyspaces(false); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); } catch (SocketException ex) { _logger.Error("There was a SocketException when trying to refresh the ControlConnection", ex); reconnect = true; } catch (Exception ex) { _logger.Error("There was an error when trying to refresh the ControlConnection", ex); } finally { Interlocked.Decrement(ref _refreshCounter); } if (reconnect) { Reconnect(); } }
/// <summary> /// Tries to create a connection to any of the contact points and retrieve cluster metadata for the first time. Not thread-safe. /// </summary> /// <exception cref="NoHostAvailableException" /> /// <exception cref="DriverInternalError" /> internal void Init() { _logger.Info("Trying to connect the ControlConnection"); //Only abort when twice the time for ConnectTimeout per host passed var initialAbortTimeout = _config.SocketOptions.ConnectTimeoutMillis * 2 * _metadata.Hosts.Count; TaskHelper.WaitToComplete(Connect(true), initialAbortTimeout); try { SubscribeEventHandlers(); RefreshNodeList(); TaskHelper.WaitToComplete(_metadata.RefreshKeyspaces(false), MetadataAbortTimeout); } catch (SocketException ex) { //There was a problem using the connection obtained //It is not usual but can happen _logger.Error("An error occurred when trying to retrieve the cluster metadata, retrying.", ex); //Retry one more time and throw if there is problem TaskHelper.WaitToComplete(Reconnect(), _config.SocketOptions.ConnectTimeoutMillis); } }
/// <summary> /// Tries to create a connection to any of the contact points and retrieve cluster metadata for the first time. Not thread-safe. /// </summary> /// <exception cref="NoHostAvailableException" /> /// <exception cref="DriverInternalError" /> internal void Init() { _logger.Info("Trying to connect the ControlConnection"); Connect(true); try { SubscribeEventHandlers(); RefreshNodeList(); Metadata.RefreshKeyspaces(false); } catch (SocketException ex) { //There was a problem using the connection obtained //It is not usual but can happen _logger.Error("An error occurred when trying to retrieve the cluster metadata, retrying.", ex); //Retry one more time and throw if there is problem Refresh(true, true); } }
internal Task <bool> Reconnect() { //If there is another thread reconnecting, use the same task var tcs = new TaskCompletionSource <bool>(); var currentTask = Interlocked.CompareExchange(ref _reconnectTask, tcs.Task, null); if (currentTask != null) { return(currentTask); } Unsubscribe(); Connect(false).ContinueWith(t => { if (t.Exception != null) { Interlocked.Exchange(ref _reconnectTask, null); tcs.TrySetException(t.Exception.InnerException); var delay = _reconnectionSchedule.NextDelayMs(); _reconnectionTimer.Change(delay, Timeout.Infinite); _logger.Error("ControlConnection was not able to reconnect: " + t.Exception.InnerException); return; } try { RefreshNodeList(); Metadata.RefreshKeyspaces(false); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); tcs.TrySetResult(true); Interlocked.Exchange(ref _reconnectTask, null); _logger.Info("ControlConnection reconnected to host {0}", _host.Address); } catch (Exception ex) { Interlocked.Exchange(ref _reconnectTask, null); _logger.Error("There was an error when trying to refresh the ControlConnection", ex); _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite); tcs.TrySetException(ex); } }); return(tcs.Task); }