private bool ChangeState([NotNull] ClientHolderState currentState, [NotNull] ClientHolderState newState) { if (Interlocked.CompareExchange(ref state, newState, currentState) != currentState) { return(false); } SendOnConnectionStateChanged(); currentState.NextState.TrySetResult(newState); log.Info("Connection state changed. Old: '{OldState}'. New: '{NewState}'.", currentState, newState); if (newState.ConnectionState == ConnectionState.Expired) { ResetClient(newState); } else if (!newState.IsConnected) { Task.Run(() => WaitAndResetClient(newState)); } else { suspendedManager.ResetDelay(); } return(true); }
private void ProcessEvent(ConnectionEvent connectionEvent) { log.Debug("Processing connection state event '{ConnectionEvent}'.", connectionEvent); var currentState = state; if (currentState == null || !ReferenceEquals(connectionEvent.EventFrom, currentState.ConnectionWatcher)) { return; } var newState = new ClientHolderState( currentState.LazyClient, currentState.ConnectionWatcher, connectionEvent.NewConnectionState, currentState.ConnectionString); if (!ChangeState(currentState, newState)) { return; } if (newState.ConnectionState == ConnectionState.Expired) { ResetClient(newState); } }
private bool ResetClientIfNeeded([CanBeNull] ClientHolderState currentState) { if (currentState != null && NeedToResetClient(currentState)) { return(ResetClient(currentState)); } return(true); }
public ClientHolder(ZooKeeperClientSettings settings, ILog log) { this.log = log; this.settings = settings; state = new ClientHolderState(null, null, ConnectionState.Disconnected, null); ZooKeeperLogInjector.Register(this, this.log); }
public ClientHolder(ZooKeeperClientSettings settings, ILog log) { this.log = log; this.settings = settings; state = ClientHolderState.CreateActive(null, null, ConnectionState.Disconnected, null, settings); suspendedManager = new SuspendedManager(settings.Timeout, settings.Timeout.Multiply(settings.MaximumConnectPeriodMultiplier), -3); ZooKeeperLogInjector.Register(this, this.log); }
private async Task WaitAndResetClient([NotNull] ClientHolderState currentState) { try { await Task.Delay(currentState.TimeBeforeReset.Remaining).ConfigureAwait(false); if (ReferenceEquals(state, currentState)) { ResetClient(currentState); } } catch (Exception e) { log.Error(e, "Failed to reset client."); } }
private bool ResetClient([NotNull] ClientHolderState currentState) { log.Info("Resetting client. Current state: '{CurrentState}'.", currentState); var newConnectionString = settings.ConnectionStringProvider(); if (string.IsNullOrEmpty(newConnectionString)) { log.Error("Failed to resolve any ZooKeeper replicas."); return(false); } var newConnectionWatcher = new ConnectionWatcher(ProcessEvent); var newClient = new Lazy <ZooKeeperNetExClient>( () => { using (ExecutionContext.SuppressFlow()) { return(new ZooKeeperNetExClient( newConnectionString, settings.ToInnerConnectionTimeout(), newConnectionWatcher, settings.CanBeReadOnly)); } }, LazyThreadSafetyMode.ExecutionAndPublication); var suspendedFor = suspendedManager.GetNextDelay(); var newState = suspendedFor != null && !currentState.IsSuspended ? ClientHolderState.CreateSuspended(suspendedFor) : ClientHolderState.CreateActive(newClient, newConnectionWatcher, ConnectionState.Disconnected, newConnectionString, settings); if (ChangeState(currentState, newState)) { newState.Client?.Touch(); // Note(kungurtsev): increase delay for each active (not suspended) client creation. if (!currentState.IsSuspended) { suspendedManager.IncreaseDelay(); } currentState.Dispose(); } return(true); }
private bool ChangeState([NotNull] ClientHolderState currentState, [NotNull] ClientHolderState newState) { if (Interlocked.CompareExchange(ref state, newState, currentState) != currentState) { return(false); } SendOnConnectionStateChanged(); currentState.NextState.TrySetResult(newState); if (currentState.ConnectionState != newState.ConnectionState) { log.Info("Connection state changed. Old: '{OldState}'. New: '{NewState}'.", currentState, newState); } return(true); }
private bool NeedToResetClient([NotNull] ClientHolderState currentState) { if (currentState.IsSuspended) { return(currentState.TimeBeforeReset.HasExpired); } if (currentState.ConnectionString != settings.ConnectionStringProvider()) { return(true); } if (!currentState.IsConnected) { return(currentState.TimeBeforeReset.HasExpired); } return(false); }
private bool ResetClient([NotNull] ClientHolderState currentState) { log.Info("Resetting client. Current state: '{CurrentState}'.", currentState); var newConnectionString = settings.ConnectionStringProvider(); if (string.IsNullOrEmpty(newConnectionString)) { log.Error("Failed to resolve any ZooKeeper replicas."); return(false); } var newConnectionWatcher = new ConnectionWatcher(ProcessEvent); var newClient = new Lazy <ZooKeeperNetExClient>( () => { using (ExecutionContext.SuppressFlow()) { return(new ZooKeeperNetExClient( newConnectionString, settings.ToInnerConnectionTimeout(), newConnectionWatcher, settings.CanBeReadOnly)); } }, LazyThreadSafetyMode.ExecutionAndPublication); var newState = new ClientHolderState(newClient, newConnectionWatcher, ConnectionState.Disconnected, newConnectionString); if (ChangeState(currentState, newState)) { newState.Client?.Touch(); currentState.Dispose(); } return(true); }