/// <inheritdoc /> public override Task <Continuation> DoAnalysisAsync(AnalysisContainer reconfigAnalysis) { Assert.IsNotNull(reconfigAnalysis, "We expect Analysis of Type ReconfigInstanceAnalysisDetails"); this.Logger.LogMessage("Current State {0}", reconfigAnalysis.GetProgressedTill()); if (reconfigAnalysis.GetProgressedTill() == ProgressTracker.NotStarted) { this.Logger.LogMessage("DoAnalysisAsync:: Populating Duration"); this.PopulateStartEndTimes((ReconfigurationAnalysisEvent)reconfigAnalysis.AnalysisEvent); reconfigAnalysis.SetProgressedTill(ProgressTracker.Finished); } if (reconfigAnalysis.GetProgressedTill() == ProgressTracker.Finished) { return(Task.FromResult(Continuation.Done)); } throw new Exception(string.Format(CultureInfo.InvariantCulture, "Progress Stage {0} not Valid", reconfigAnalysis.GetProgressedTill())); }
/// <inheritdoc /> public override async Task <Continuation> DoAnalysisAsync(AnalysisContainer analysis) { if (analysis.GetProgressedTill() == ProgressTracker.NotStarted) { PrimaryMoveAnalysisEvent primaryMoveAnalysisEvent = analysis.AnalysisEvent as PrimaryMoveAnalysisEvent; primaryMoveAnalysisEvent.Reason = PrimaryMoveReason.Unknown; var reconfigRecord = primaryMoveAnalysisEvent.TriggerReconfigurationCompletedTraceRecord; primaryMoveAnalysisEvent.PreviousPrimaryContext = await this.primaryReplicaContextStore.GetPrimaryReplicaContextAsync(reconfigRecord.PartitionId).ConfigureAwait(false); if (primaryMoveAnalysisEvent.PreviousPrimaryContext == null) { this.Logger.LogWarning("PreviousPrimaryContext is null, cannot perform PrimaryMoveAnalysis."); analysis.SetProgressedTill(ProgressTracker.Finished); return(Continuation.Done); } primaryMoveAnalysisEvent.CurrentPrimaryContext = new PrimaryReplicaContext(reconfigRecord.PartitionId, reconfigRecord.NodeName, reconfigRecord.NodeInstanceId, reconfigRecord.TimeStamp.Ticks); if (primaryMoveAnalysisEvent.CurrentPrimaryContext == null) { this.Logger.LogWarning("CurrentPrimaryContext is null, cannot perform PrimaryMoveAnalysis."); analysis.SetProgressedTill(ProgressTracker.Finished); return(Continuation.Done); } // CurrentPrimaryContext becomes the PreviousPrimaryContext for the next analysis await this.primaryReplicaContextStore.SavePrimaryReplicaContextAsync(primaryMoveAnalysisEvent.CurrentPrimaryContext).ConfigureAwait(false); analysis.SetProgressedTill(ProgressTracker.Checkpoint1); return(Continuation.ResumeImmediately); } else if (analysis.GetProgressedTill() == ProgressTracker.Checkpoint1) { PrimaryMoveAnalysisEvent primaryMoveAnalysisEvent = analysis.AnalysisEvent as PrimaryMoveAnalysisEvent; if (primaryMoveAnalysisEvent.TriggerReconfigurationCompletedTraceRecord.ReconfigType == ReconfigurationType.Failover) { primaryMoveAnalysisEvent.Reason = PrimaryMoveReason.Failover; analysis.SetProgressedTill(ProgressTracker.Checkpoint2); return(Continuation.ResumeImmediately); } else if (primaryMoveAnalysisEvent.TriggerReconfigurationCompletedTraceRecord.ReconfigType == ReconfigurationType.SwapPrimary) { primaryMoveAnalysisEvent.Reason = PrimaryMoveReason.SwapPrimary; analysis.SetProgressedTill(ProgressTracker.Checkpoint3); return(Continuation.ResumeImmediately); } } else if (analysis.GetProgressedTill() == ProgressTracker.Checkpoint2) { PrimaryMoveAnalysisEvent primaryMoveAnalysisEvent = analysis.AnalysisEvent as PrimaryMoveAnalysisEvent; bool dueToNodeDown = await this.AnalyzeNodeDownAsync(primaryMoveAnalysisEvent).ConfigureAwait(false); if (!dueToNodeDown) { analysis.SetProgressedTill(ProgressTracker.Checkpoint4); return(Continuation.ResumeImmediately); } else { analysis.SetProgressedTill(ProgressTracker.Finished); primaryMoveAnalysisEvent.AnalysisEndTimeStamp = DateTime.UtcNow; return(Continuation.Done); } } else if (analysis.GetProgressedTill() == ProgressTracker.Checkpoint3) { PrimaryMoveAnalysisEvent primaryMoveAnalysisEvent = analysis.AnalysisEvent as PrimaryMoveAnalysisEvent; await this.AnalyzeCRMOperationAsync(primaryMoveAnalysisEvent).ConfigureAwait(false); analysis.SetProgressedTill(ProgressTracker.Finished); primaryMoveAnalysisEvent.AnalysisEndTimeStamp = DateTime.UtcNow; return(Continuation.Done); } else if (analysis.GetProgressedTill() == ProgressTracker.Checkpoint4) { PrimaryMoveAnalysisEvent primaryMoveAnalysisEvent = analysis.AnalysisEvent as PrimaryMoveAnalysisEvent; var replicaStateChangeTraceRecordList = await this.primaryMoveAnalysisQueryStoreReader.GetReplicaStateChangeTraceRecordsAsync(primaryMoveAnalysisEvent).ConfigureAwait(false); if (replicaStateChangeTraceRecordList == null || !replicaStateChangeTraceRecordList.Any()) { this.Logger.LogWarning("No replica closing traces found with duration {0}, cannot perform further analysis.", primaryMoveAnalysisEvent.GetDuration()); analysis.SetProgressedTill(ProgressTracker.Finished); return(Continuation.Done); } primaryMoveAnalysisEvent.ReasonActivityId = replicaStateChangeTraceRecordList.First().ReasonActivityId; primaryMoveAnalysisEvent.ReasonActivityType = replicaStateChangeTraceRecordList.First().ReasonActivityType; primaryMoveAnalysisEvent.AddCorrelatedTraceRecordRange(replicaStateChangeTraceRecordList); if (replicaStateChangeTraceRecordList.First().ReasonActivityType == ActivityType.ServicePackageEvent) { primaryMoveAnalysisEvent.Reason = PrimaryMoveReason.ApplicationHostDown; analysis.SetProgressedTill(ProgressTracker.Checkpoint5); return(Continuation.ResumeImmediately); } else if (replicaStateChangeTraceRecordList.First().ReasonActivityType == ActivityType.ClientReportFaultEvent || replicaStateChangeTraceRecordList.First().ReasonActivityType == ActivityType.ServiceReportFaultEvent) { // TODO: Break report fault analysis into two separate analyses because ReplicaStateChange already shows which one of the two happened primaryMoveAnalysisEvent.Reason = PrimaryMoveReason.ClientApiReportFault; analysis.SetProgressedTill(ProgressTracker.Checkpoint6); return(Continuation.ResumeImmediately); } } else if (analysis.GetProgressedTill() == ProgressTracker.Checkpoint5) { PrimaryMoveAnalysisEvent primaryMoveAnalysisEvent = analysis.AnalysisEvent as PrimaryMoveAnalysisEvent; await this.AnalyzeAppHostDownAsync(primaryMoveAnalysisEvent).ConfigureAwait(false); analysis.SetProgressedTill(ProgressTracker.Finished); primaryMoveAnalysisEvent.AnalysisEndTimeStamp = DateTime.UtcNow; return(Continuation.Done); } else if (analysis.GetProgressedTill() == ProgressTracker.Checkpoint6) { PrimaryMoveAnalysisEvent primaryMoveAnalysisEvent = analysis.AnalysisEvent as PrimaryMoveAnalysisEvent; await this.AnalyzeReportFaultAsync(primaryMoveAnalysisEvent).ConfigureAwait(false); analysis.SetProgressedTill(ProgressTracker.Finished); primaryMoveAnalysisEvent.AnalysisEndTimeStamp = DateTime.UtcNow; return(Continuation.Done); } throw new Exception(string.Format(CultureInfo.InvariantCulture, "Progress Stage {0} not Valid", analysis.GetProgressedTill())); }