/// <summary> /// Sets the <see cref="Status"/> property and raised the <see cref="StatusChanged"/> event /// </summary> /// <param name="requestId">The requestId of the recovery request which caused the change or a null reference</param> /// <param name="newStatus">The <see cref="ProducerRecoveryStatus"/> specifying the new status</param> /// <remarks>Should be used only within locking</remarks> private void SetStatusAndRaiseEvent(long?requestId, ProducerRecoveryStatus newStatus) { var oldStatus = Status; if (Status == newStatus) { ExecutionLog.LogDebug($"{Producer.Name}: Attempting to set status to an existing value {Status}. Aborting ..."); return; } ExecutionLog.LogInformation($"{Producer.Name} Status changed from {oldStatus} to {newStatus}."); Status = newStatus; _producer.SetProducerDown(newStatus != ProducerRecoveryStatus.Completed); Task.Run(() => { try { _semaphoreStatusChange.Wait(); StatusChanged?.Invoke(this, new TrackerStatusChangeEventArgs(requestId, oldStatus, newStatus)); } catch (Exception ex) { ExecutionLog.LogError(ex, $"{Producer.Name} Status change event failed."); } finally { _semaphoreStatusChange.ReleaseSafe(); } }); }
/// <summary> /// Initializes a new instance of the <see cref="ProducerRecoveryManager"/> class /// </summary> /// <param name="producer">A <see cref="IProducer"/> for which status is tracked</param> /// <param name="recoveryOperation">A <see cref="IRecoveryOperation"/> used to issue and track recovery operations</param> /// <param name="timestampTracker">A <see cref="ITimestampTracker"/> used to track message timings</param> internal ProducerRecoveryManager(IProducer producer, IRecoveryOperation recoveryOperation, ITimestampTracker timestampTracker) { Guard.Argument(producer, nameof(producer)).NotNull(); Guard.Argument(recoveryOperation, nameof(recoveryOperation)).NotNull(); Guard.Argument(timestampTracker, nameof(timestampTracker)).NotNull(); Producer = producer; _producer = (Producer)producer; _recoveryOperation = recoveryOperation; _timestampTracker = timestampTracker; Status = ProducerRecoveryStatus.NotStarted; }
/// <summary> /// Initializes a new instance of the <see cref="ProducerRecoveryManager"/> class /// </summary> /// <param name="producer">A <see cref="IProducer"/> for which status is tracked</param> /// <param name="recoveryOperation">A <see cref="IRecoveryOperation"/> used to issue and track recovery operations</param> /// <param name="timestampTracker">A <see cref="ITimestampTracker"/> used to track message timings</param> internal ProducerRecoveryManager(IProducer producer, IRecoveryOperation recoveryOperation, ITimestampTracker timestampTracker) { Contract.Requires(producer != null); Contract.Requires(recoveryOperation != null); Contract.Requires(timestampTracker != null); Producer = producer; _producer = (Producer)producer; _recoveryOperation = recoveryOperation; _timestampTracker = timestampTracker; Status = ProducerRecoveryStatus.NotStarted; }
/// <summary> /// Initializes a new instance of the <see cref="ProducerRecoveryManager"/> class /// </summary> /// <param name="producer">A <see cref="IProducer"/> for which status is tracked</param> /// <param name="recoveryOperation">A <see cref="IRecoveryOperation"/> used to issue and track recovery operations</param> /// <param name="timestampTracker">A <see cref="ITimestampTracker"/> used to track message timings</param> /// <param name="minIntervalBetweenRecoveryRequests">The minimal interval between recovery requests initiated by alive messages (seconds)</param> internal ProducerRecoveryManager(IProducer producer, IRecoveryOperation recoveryOperation, ITimestampTracker timestampTracker, int minIntervalBetweenRecoveryRequests) { Guard.Argument(producer, nameof(producer)).NotNull(); Guard.Argument(recoveryOperation, nameof(recoveryOperation)).NotNull(); Guard.Argument(timestampTracker, nameof(timestampTracker)).NotNull(); Producer = producer; _producer = (Producer)producer; _recoveryOperation = recoveryOperation; _timestampTracker = timestampTracker; _minIntervalBetweenRecoveryRequests = minIntervalBetweenRecoveryRequests; Status = ProducerRecoveryStatus.NotStarted; _lastRecoveryMessage = DateTime.Now; _connectionDownTimestamp = DateTime.MinValue; }
/// <summary> /// Sets the <see cref="Status"/> property and raised the <see cref="StatusChanged"/> event /// </summary> /// <param name="requestId">The requestId of the recovery request which caused the change or a null reference</param> /// <param name="newStatus">The <see cref="ProducerRecoveryStatus"/> specifying the new status</param> /// <remarks>Should be used only within locking</remarks> private void SetStatusAndRaiseEvent(long?requestId, ProducerRecoveryStatus newStatus) { var oldStatus = Status; if (Status == newStatus) { ExecutionLog.LogDebug($"{Producer.Name}: Attempting to set status to an existing value {Status}. Aborting ..."); return; } ExecutionLog.LogInformation($"{Producer.Name} Status changed from {Status} to {newStatus}."); Status = newStatus; _producer.SetProducerDown(newStatus != ProducerRecoveryStatus.Completed); Task.Run(() => { StatusChanged?.Invoke(this, new TrackerStatusChangeEventArgs(requestId, oldStatus, newStatus)); }); }
/// <summary> /// Initializes a new instance of the <see cref="TrackerStatusChangeEventArgs"/> class. /// </summary> /// <param name="requestId"> /// The <see cref="long"/> specifying the id of the requestId of the recovery operation which caused this change, /// or a null reference if the change was not by a recovery request. /// </param> /// <param name="oldStatus">The <see cref="ProducerRecoveryStatus"/> specifying the status of the tracker before the change.</param> /// <param name="newStatus">The <see cref="ProducerRecoveryStatus"/> specifying the status of the tracker after the change.</param> public TrackerStatusChangeEventArgs(long?requestId, ProducerRecoveryStatus oldStatus, ProducerRecoveryStatus newStatus) { RequestId = requestId; OldStatus = oldStatus; NewStatus = newStatus; }