Esempio n. 1
0
        internal Duration GetDuration()
        {
            if (this.duration == null)
            {
                Assert.IsTrue(this.PreviousPrimaryContext != null && this.CurrentPrimaryContext != null, "We need both previous primary timestamp and current primary time stamp.");

                long betweenMovesSpanTicks = this.CurrentPrimaryContext.DateTimeUtcTicks - this.PreviousPrimaryContext.DateTimeUtcTicks;

                if (betweenMovesSpanTicks > PrimaryReplicaContextConstants.TraceReadTimeSpanMaxTicks)
                {
                    long traceReadTimeSpanMaxEarlierTicks = this.CurrentPrimaryContext.DateTimeUtcTicks - PrimaryReplicaContextConstants.TraceReadTimeSpanMaxTicks;
                    this.duration = new Duration(traceReadTimeSpanMaxEarlierTicks, this.CurrentPrimaryContext.DateTimeUtcTicks);
                }
                else
                {
                    this.duration = new Duration(this.PreviousPrimaryContext.DateTimeUtcTicks, this.CurrentPrimaryContext.DateTimeUtcTicks);
                }
            }

            return(this.duration);
        }
Esempio n. 2
0
        /// <summary>
        /// Not all reconfigurations are interesting, here we filter further.
        /// </summary>
        /// <param name="targetEntity"></param>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public override async Task <bool> IsEligibleForAnalysisAsync(BaseEntity targetEntity, ScenarioData data)
        {
            Assert.IsNotNull(targetEntity, "targetEntity");
            Assert.IsNotNull(data, "data");

            var reconfig = data.TraceRecord as ReconfigurationCompletedTraceRecord;

            Assert.IsNotNull(
                reconfig,
                string.Format(CultureInfo.InvariantCulture, "Actual Type: {0}, Expected: {1}", data.TraceRecord.GetType(), typeof(ReconfigurationCompletedTraceRecord)));

            var partitionEntity = targetEntity as PartitionEntity;

            if (partitionEntity == null)
            {
                this.Logger.LogWarning("targetEntity is not a ParitionEntity, thus ineligible for primary move analysis.", reconfig.PartitionId);
                return(false);
            }

            // We only do analysis for stateful service partitions
            if (partitionEntity.ServiceKind != System.Fabric.Query.ServiceKind.Stateful)
            {
                this.Logger.LogWarning("Partition Id {0} does not belong to a stateful partition, so PrimaryMoveAnalysis does not apply.", reconfig.PartitionId);
                return(false);
            }

            bool primaryPreviousLocationKnown = await this.primaryReplicaContextStore.IsPartitionIdKnownAsync(reconfig.PartitionId).ConfigureAwait(false);

            // Registers the primary location for the first time depending on RA.ReconfigurationCompleted with ReconfigType == Other
            // Afterwards, updates of the primary location is done in the DoAnalysisAsync which happens only for Failover and SwapPrimary type reconfigurations
            if (!primaryPreviousLocationKnown)
            {
                PrimaryReplicaContext primaryReplicaContext = new PrimaryReplicaContext(reconfig.PartitionId, reconfig.NodeName, reconfig.NodeInstanceId, reconfig.TimeStamp.Ticks);
                await this.primaryReplicaContextStore.SavePrimaryReplicaContextAsync(primaryReplicaContext).ConfigureAwait(false);
            }

            return(this.ShouldPerformAnalysis(reconfig, primaryPreviousLocationKnown));
        }