Beispiel #1
0
        /// <summary>
        /// Processes the <see cref="snapshot_complete"/> message. Only snapshot_complete(s) from user's sessions should be processed
        /// </summary>
        /// <param name="snapshotCompleted">The <see cref="snapshot_complete"/> message received on the system user's session</param>
        /// <param name="interest">The <see cref="MessageInterest"/> associated with the session which received the message</param>
        /// <returns>A <see cref="ProducerRecoveryStatus"/> specifying the new status of the manager or null reference if no change is needed</returns>
        private ProducerRecoveryStatus?ProcessSnapshotCompleteMessage(snapshot_complete snapshotCompleted, MessageInterest interest)
        {
            URN eventId;

            if (_producer.EventRecoveries.TryRemove(snapshotCompleted.request_id, out eventId))
            {
                ExecutionLog.Info($"Recovery with requestId={snapshotCompleted.request_id} for producer={Producer.Id}, eventId={eventId} completed.");
                EventRecoveryCompleted?.Invoke(this, new EventRecoveryCompletedEventArgs(snapshotCompleted.request_id, eventId));
                return(null);
            }

            //The snapshot message not for us
            if (!_recoveryOperation.IsRunning || !_recoveryOperation.RequestId.HasValue || _recoveryOperation.RequestId.Value != snapshotCompleted.RequestId)
            {
                return(null);
            }

            //Debug.Assert(Status == ProducerRecoveryStatus.Started);

            RecoveryResult recoveryResult;

            ExecutionLog.Debug($"SnapshotComplete[{"requestId" + snapshotCompleted.request_id}] for producer=[{"id=" + Producer.Id}] on session {interest.Name} received");
            if (!_recoveryOperation.TryComplete(interest, out recoveryResult))
            {
                //The recovery is not complete, nothing to do.
                ExecutionLog.Debug($"Recovery with requestId={snapshotCompleted.request_id} for producer={Producer.Id} is not yet completed. Waiting for snapshots from other sessions");
                return(null);
            }

            // The recovery operation completed. Check the result and act accordingly
            if (recoveryResult.Success)
            {
                // the recovery was interrupted
                if (recoveryResult.InterruptedAt.HasValue)
                {
                    ExecutionLog.Warn($"Recovery with requestId={snapshotCompleted.request_id} for producer={Producer.Id} completed with interruption at:{recoveryResult.InterruptedAt.Value}");
                    _producer.SetLastTimestampBeforeDisconnect(recoveryResult.InterruptedAt.Value);
                    return(ProducerRecoveryStatus.Error);
                }
                // the recovery was not interrupted
                var recoveryDuration = TimeProviderAccessor.Current.Now - recoveryResult.StartTime;
                ExecutionLog.Info($"Recovery with requestId={snapshotCompleted.request_id} for producer={Producer.Id} completed in {recoveryDuration.TotalSeconds} sec.");
                _producer.SetLastTimestampBeforeDisconnect(SdkInfo.FromEpochTime(snapshotCompleted.timestamp));
                return(_timestampTracker.IsBehind
                           ? ProducerRecoveryStatus.Delayed
                           : ProducerRecoveryStatus.Completed);
            }

            // The recovery operation timed-out
            var timeOutDuration = TimeProviderAccessor.Current.Now - recoveryResult.StartTime;

            ExecutionLog.Warn($"Recovery with requestId={snapshotCompleted.RequestId} timed out after:{timeOutDuration}");
            return(ProducerRecoveryStatus.Error);
        }
Beispiel #2
0
 /// <summary>
 /// Handles the event recovery completion of a specific recovery manager
 /// </summary>
 /// <param name="sender">An <see cref="object"/> representation of a <see cref="IProducerRecoveryManager"/> instance whose status has changed.</param>
 /// <param name="e">The <see cref="EventRecoveryCompletedEventArgs"/>Additional information about the event.</param>
 private void OnRecoveryTrackerEventRecoveryCompleted(object sender, EventRecoveryCompletedEventArgs e)
 {
     EventRecoveryCompleted?.Invoke(this, e);
 }