Exemple #1
0
 public ScenarioData(Scenario scenario, TraceRecord record, DateTime eventSeenTime)
 {
     Assert.IsNotNull(record, "TraceRecord can't be null");
     this.Scenario      = scenario;
     this.TraceRecord   = record;
     this.EventSeenTime = eventSeenTime;
 }
Exemple #2
0
        internal void SetContinuation(Continuation continueBehavior)
        {
            Assert.IsNotNull(continueBehavior);
            this.continuation = continueBehavior;
            if (this.continuation.Equals(Continuation.Done))
            {
                this.currentStatus = AnalysisStatus.Completed;
                return;
            }

            switch (this.continuation.ContinuationType)
            {
            case ContinuationType.WaitForTime:
                Assert.IsTrue(this.continuation.SuspendTimeout.HasValue, "Suspend Timeout should have value");
                this.currentStatus      = AnalysisStatus.Suspended;
                this.nextActivationTime = DateTime.UtcNow.Add(this.continuation.SuspendTimeout.Value);
                break;

            case ContinuationType.WaitForFabricEvent:
                this.currentStatus = AnalysisStatus.Suspended;
                break;

            case ContinuationType.WaitForInterest:
                this.currentStatus = AnalysisStatus.Suspended;
                break;

            default:
                throw new NotSupportedException(string.Format(
                                                    CultureInfo.InvariantCulture,
                                                    "Continuation Type: {0} is Unsupported",
                                                    this.continuation.ContinuationType));
            }
        }
Exemple #3
0
 public ScenarioNotificationData(ScenarioData scenarioData, NotifyFilter filter)
 {
     Assert.IsNotNull(scenarioData, "scenarioData");
     Assert.IsNotNull(filter, "filter");
     this.ScenarioData = scenarioData;
     this.Filter       = filter;
 }
Exemple #4
0
        protected BaseCallbackStore(IStoreProvider storeProvider, ITaskRunner taskRunner, ILogProvider logProvider, CancellationToken token)
        {
            Assert.IsNotNull(storeProvider, "Store Provider can't be null");
            Assert.IsNotNull(taskRunner, "Task Runner can't be null");
            Assert.IsNotNull(logProvider, "Log Provider can't be null");

            this.singleAccessLock = new SemaphoreSlim(1);
            this.callbackMap      = new Dictionary <NotifyFilter, IList <Func <ScenarioData, Task> > >();
            this.Logger           = logProvider.CreateLoggerInstance(this.GetType().ToString().Split('.').Last());
            this.taskRunner       = taskRunner;

            this.InternalTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
            token = this.InternalTokenSource.Token;

            // Some signals may not show up immedietly so we don't want their last seen time bailing on us.
            this.callBackCheckPointTimeStore = storeProvider.CreatePersistentStoreForTimeAsync(CallbackTimeBookmarkStore, AgeBasedRetentionPolicy.OneDay, token)
                                               .GetAwaiter().GetResult();

            // This store keeps track of unique Ids of signals seen to avoid duplicate reporting. The entries in this
            // collection needs to be long lived. Consider a signal that is living in the system for a long time
            // If we don't track that this has been reported, we may try to report it again.
            this.reportedSignalsUniqueIdsStore = storeProvider
                                                 .CreatePersistentStoreKeyGuidValueStringAsync(ReportedSignalUniqueIdsStoreName, AgeBasedRetentionPolicy.OneWeek, token).GetAwaiter()
                                                 .GetResult();

            this.signalsInDispatchQueuePersistentStore = storeProvider
                                                         .CreatePersistentStoreKeyGuidValueStringAsync(SignalsInDispatchQueueStoreName, AgeBasedRetentionPolicy.OneHour, token).GetAwaiter().GetResult();

            this.producerConsumerBufferBlock = new BufferBlock <ScenarioNotificationData>();
            this.InitSignalSeenBookmarkStoreAsync(token).Wait(token);
        }
        private void InitTimeTriggeredAgentScheduling()
        {
            var timeTriggeredAgents = this.GetTimeTriggeredAgents();

            if (timeTriggeredAgents == null)
            {
                return;
            }

            this.Logger.LogMessage(
                "InitSignalTriggeredAgentScheduling:: Time Triggered Agents List: '{0}'",
                string.Join(";", timeTriggeredAgents.Select(agent => agent.GetType())));

            foreach (var oneAgentIdentifier in timeTriggeredAgents)
            {
                var timeTriggeredAgent = AgentDirectory.SingleInstance.GetOrCreateAgentInstance(oneAgentIdentifier) as TimeTriggeredAgent;
                Assert.IsNotNull(timeTriggeredAgent, string.Format("Agent Identifier : {0} Not a Time Triggered Agent", oneAgentIdentifier));
                Task.Run(() => this.RunRegularlyAtIntervalAsync(timeTriggeredAgent), this.InsightLocalToken).ContinueWith(
                    task =>
                {
                    this.Logger.LogError("BaseInsightGenerator:: Task Encountered unexpected Exception '{0}'", task.Exception);
                    Environment.FailFast(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "BaseStore:: Exception Encountered '{0}'",
                            task.Exception != null ? task.Exception.ToString() : "None"),
                        task.Exception);
                },
                    TaskContinuationOptions.OnlyOnFaulted);
            }
        }
        protected async Task DispatchSignalToAgentsAsync(BaseEntity targetEntity, ScenarioData scenarioData)
        {
            var agentIdentifers = this.GetSignalTriggeredAgents();

            if (agentIdentifers == null)
            {
                return;
            }

            bool signalDispatched = false;

            foreach (var oneAgentifier in agentIdentifers)
            {
                Assert.IsNotNull(AgentDirectory.SingleInstance, "AgentDirectory.SingleInstance != null");
                if (AgentDirectory.SingleInstance.GetOrCreateAgentInstance(oneAgentifier).NotifyFilters.Any(item => item.TargetScenario == scenarioData.Scenario))
                {
                    await this.analysisScheduler.StartAsync(oneAgentifier, targetEntity, scenarioData).ConfigureAwait(false);

                    signalDispatched = true;
                }
            }

            if (!signalDispatched)
            {
                throw new Exception(string.Format("Error Condition: No Target found for Scenario: {0}", scenarioData.Scenario));
            }
        }
        /// <summary>
        /// Save signals for a specific container in a queue. This is done in scenario where the container
        /// is not yet ready to accept signals.
        /// </summary>
        /// <param name="analysis"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private Task SaveToQueueAsync(AnalysisContainer analysis, ScenarioData data)
        {
            Assert.IsNotNull(data, "data");
            var key = analysis.GetUniqueIdentity();

            ConcurrentQueue <ScenarioData> existingQueue;

            if (this.signalWaitingToBeProcessedMap.TryGetValue(key, out existingQueue))
            {
                if (existingQueue.Contains(data))
                {
                    throw new SignalAlreadyPresentException(string.Format(CultureInfo.InvariantCulture, "Save Queue. Analysis: {0}, Data: {1}", analysis, data));
                }

                existingQueue.Enqueue(data);
            }
            else
            {
                // A tiny window exists for race condition. I thought about using AddOrUpdate but that won't help either since
                // the update lambda is called outside lock. So keep it the way it is for now. In future, consider using a lock
                // for entire operation.
                existingQueue = this.signalWaitingToBeProcessedMap.GetOrAdd(key, new ConcurrentQueue <ScenarioData>(new[] { data }));
            }

            // Persist it.
            return(this.signalWaitingToBeProcessedStoreInstance.SetEntityAsync(
                       data.GetUniqueIdentity(),
                       HandyUtil.Serialize(existingQueue),
                       this.CancelToken));
        }
        private async Task InitializeSignalTriggeredAgentsAsync()
        {
            var signalTriggeredAgents = this.GetSignalTriggeredAgents();

            if (signalTriggeredAgents == null)
            {
                return;
            }

            this.Logger.LogMessage(
                "InitializeSignalTriggeredAgentsAsync:: Signal Triggered Agents List: '{0}'",
                string.Join(";", signalTriggeredAgents));

            // Ok, so some complicated linq magic going on. Here is what we are trying to do. So different agents may be interested in the same scenario,
            // but their notify duration (i.e. signal age) may be different. In such cases, we first group filters by scenario and then for each scenario register with the "minimum"
            // of Notify duration among the group. When we will ultimately receive the signals, while dispatching them to the agents, we would check again
            // if along with their scenario, does their notify duration condition is satisfied or not.
            Assert.IsNotNull(AgentDirectory.SingleInstance, "AgentDirectory.SingleInstance != null");
            var allFilters = signalTriggeredAgents.SelectMany(agentIdentifier => AgentDirectory.SingleInstance.GetOrCreateAgentInstance(agentIdentifier).NotifyFilters);

            var uniqueFilters = allFilters.GroupBy(item => item.TargetScenario).ToDictionary(
                gp => gp.Key,
                gp => gp.ToList().OrderBy(item => item.SignalAvailableForAtLeastDuration).First());

            foreach (var singleFilter in uniqueFilters.Values)
            {
                this.Logger.LogMessage("InitializeSignalTriggeredAgentsAsync:: Registering callback for scenario : '{0}'", singleFilter);
                await this.CallbackStore.RegisterCallbackAsync(singleFilter, this.HandleIncomingEventNotificationAsync, this.InsightLocalToken).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Check if a container is in position to accept updates
        /// </summary>
        /// <remarks>
        /// Updates can only be accepted once main analysis is finished. This routines checks that.
        /// </remarks>
        /// <param name="analysis"></param>
        /// <returns></returns>
        private async Task <bool> IsAnalysisContainerInPositionToAcceptEventsAsync(AnalysisContainer analysis)
        {
            Assert.IsNotNull(analysis, "analysis");
            var schedulingInfo = (await this.analysisMetadataObjectStore.GetTypedObjectAsync(analysis.GetUniqueIdentity()).ConfigureAwait(false)).SchedulingInfo;

            return(schedulingInfo.CurrentStatus == AnalysisStatus.Suspended && schedulingInfo.GetContinuationType() == ContinuationType.WaitForInterest);
        }
        /// <summary>
        /// Entry point for a an Analysis container to Begin. This is true for the main analysis as well
        /// as the update to an existing analysis container
        /// </summary>
        /// <param name="analysis"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private async Task ScheduleAnalysisAsync(AnalysisContainer analysis)
        {
            Assert.IsNotNull(analysis, "analysis");

            var key = analysis.GetUniqueIdentity();

            this.Logger.LogMessage("ScheduleAnalysisAsync : Key : {0}", key);

            // Get the Associated Analysis Metadata.
            var analysisMetadata = await this.analysisMetadataObjectStore.GetOrAddTypedObjectAsync(key, new AnalysisMetadata(key)).ConfigureAwait(false);

            if (analysis.InterestFilter != null)
            {
                analysisMetadata.HasRegisteredInterest = true;
                await this.analysisMetadataObjectStore.PersistTypedObjectAsync(analysisMetadata).ConfigureAwait(false);
            }

            this.AssertIfComputePipelineInFaultedState();

            // Push the signal into our dataflow pipeline.
            var result = await this.signalConsumeDataFlow.SendAsync(analysis, this.CancelToken).ConfigureAwait(false);

            if (!result)
            {
                this.Logger.LogWarning(string.Format(CultureInfo.InvariantCulture, "Failed to Process Analysis: '{0}'", analysis));
                throw new Exception(string.Format(CultureInfo.InvariantCulture, "Failed to Process Analysis: '{0}'", analysis));
            }
        }
Exemple #11
0
 /// <summary>
 /// Mark analysis as finished.
 /// </summary>
 /// <remarks>
 /// Only NotStarted -> Queued or Suspended -> Queued are supported transitions.
 /// </remarks>
 internal void MarkQueued()
 {
     Assert.IsTrue(
         this.currentStatus == AnalysisStatus.NotStarted || this.currentStatus == AnalysisStatus.Suspended,
         () => string.Format(CultureInfo.InvariantCulture, "Current Status {0} -> Queued Not valid", this.currentStatus));
     this.currentStatus = AnalysisStatus.Queued;
 }
Exemple #12
0
 internal void AddExceptionSeen(Exception exp)
 {
     Assert.IsNotNull(exp);
     if (this.exceptionEncountered == null)
     {
         this.exceptionEncountered = new List <string>();
     }
 }
Exemple #13
0
        internal TraceRecord GetEventBeingWaitedOn()
        {
            Assert.IsTrue(this.currentStatus == AnalysisStatus.Suspended, string.Format(CultureInfo.InvariantCulture, "This routine not valid when Current status: {0}", this.currentStatus));
            if (this.continuation.ContinuationType != ContinuationType.WaitForFabricEvent)
            {
                return(null);
            }

            return(this.continuation.TraceRecord);
        }
Exemple #14
0
 /// <summary>
 /// Create an instance of <see cref="SimpleCallbackStore"/>
 /// </summary>
 /// <param name="logProvider"></param>
 /// <param name="traceStoreReader"></param>
 /// <param name="token"></param>
 /// <param name="storeProvider"></param>
 /// <param name="taskRunner"></param>
 /// <remarks>
 /// Keeping private to control who can create an instance.
 /// </remarks>
 internal SimpleCallbackStore(
     IStoreProvider storeProvider,
     ITaskRunner taskRunner,
     ILogProvider logProvider,
     ITraceStoreReader traceStoreReader,
     CancellationToken token) : base(storeProvider, taskRunner, logProvider, token)
 {
     Assert.IsNotNull(traceStoreReader, "Trace Store Reader can't be null");
     this.traceStoreReader = traceStoreReader;
 }
Exemple #15
0
        internal void MarkFailed()
        {
            Assert.IsTrue(
                this.currentStatus == AnalysisStatus.InProgress,
                () => string.Format(CultureInfo.InvariantCulture, "Transition From Current Status: {0} -> Failed Not valid", this.currentStatus));

            this.currentStatus = AnalysisStatus.Failed;

            this.analysisEndTime = DateTime.UtcNow.ToUniversalTime();
        }
        // TODO: Make Async
        public static BaseEntity ExtractClusterEntity(ILogger logger, IClusterQuery clusterQuery, TraceRecord traceRecord, CancellationToken cancelToken)
        {
            Assert.IsNotNull(clusterQuery);
            Assert.IsNotNull(traceRecord);

            if (traceRecord is ReconfigurationCompletedTraceRecord)
            {
                return((BaseEntity)ExtractPartitionEntityFromReconfigEvent(clusterQuery, (ReconfigurationCompletedTraceRecord)traceRecord, cancelToken));
            }

            throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' Event not supported", traceRecord.GetType()));
        }
        public async Task StartAsync(AgentIdentifier agentIdentifier, BaseEntity targetEntity, ScenarioData scenarioData)
        {
            Assert.IsNotNull(targetEntity, "targetEntity");
            Assert.IsNotNull(scenarioData, "scenarioData");

            // Create a new, or retreive an existing container for analyzing this interesting event
            var container = await this.GetAnalysisContainerInterestedInEventAsync(scenarioData.TraceRecord).ConfigureAwait(false);

            // This implies that there is an existing analysis which is waiting for this signal.
            if (container != null)
            {
                Assert.IsTrue(
                    targetEntity.Equals(container.AnalysisEvent.TargetEntity),
                    string.Format(CultureInfo.InvariantCulture, "Entity Mismatch: New: {0}, Existing: {1}", targetEntity, container.AnalysisEvent.TargetEntity));

                // Update the scenario data that is the reason this analysis container got resumed.
                container.CurrentInvokationData = scenarioData;

                // TODO: Do Atomically.
                if (await this.IsAnalysisContainerInPositionToAcceptEventsAsync(container).ConfigureAwait(false))
                {
                    // Push the analysis into analysis compute queue
                    await this.ScheduleAnalysisAsync(container).ConfigureAwait(false);
                }
                else
                {
                    await this.SaveToQueueAsync(container, scenarioData).ConfigureAwait(false);
                }
            }
            else
            {
                Assert.IsNotNull(AgentDirectory.SingleInstance, "AgentDirectory.SingleInstance != null");
                var agent = AgentDirectory.SingleInstance.GetOrCreateAgentInstance(agentIdentifier);

                // Check if this signal is eligible for further analysis.
                if (!await agent.IsEligibleForAnalysisAsync(targetEntity, scenarioData).ConfigureAwait(false))
                {
                    return;
                }

                container = agent.CreateNewAnalysisContainer(scenarioData.TraceRecord);

                // Update the analysis with information on the target entity.
                container.AnalysisEvent.TargetEntity = targetEntity;

                // Update the scenario data that is the reason this analysis container got created/resumed.
                container.CurrentInvokationData = scenarioData;

                // Push the analysis into analysis compute queue
                await this.ScheduleAnalysisAsync(container).ConfigureAwait(false);
            }
        }
 /// <inheritdoc />
 internal ReconfigAnalysisAgent(
     Config config,
     ITaskRunner taskRunner,
     ILogger logger,
     IStoreProvider storeProvider,
     ITraceStoreReader eventStoreReader,
     ITraceStoreReader queryStoreReader,
     IClusterQuery clusterQuery,
     CancellationToken token) : base(taskRunner, logger, storeProvider, eventStoreReader, queryStoreReader, clusterQuery, token)
 {
     Assert.IsNotNull(config, "Config can't be null");
     this.currentConfig = config.NamedConfigManager.GetConfiguration <ReconfigAnalysisAgentConfig>();
     this.Logger.LogMessage("Init with Config: {0}", this.currentConfig);
 }
Exemple #19
0
        /// <summary>
        /// Mark status as started
        /// </summary>
        /// <remarks>
        /// Only NotStarted -> Started or Queued -> Started are supported.
        /// TODO:: Fix Suspended???
        /// </remarks>
        internal void MarkStarted()
        {
            Assert.IsFalse(this.IsOutOfAttempts(), "Already out of Attempts. Can't be transitioned to started");
            Assert.IsTrue(
                this.currentStatus == AnalysisStatus.NotStarted || this.currentStatus == AnalysisStatus.Queued || this.currentStatus == AnalysisStatus.Suspended,
                string.Format(CultureInfo.InvariantCulture, "Transition From Current Status: {0} -> Started Not valid", this.currentStatus));

            this.currentStatus = AnalysisStatus.InProgress;

            if (this.currentStatus == AnalysisStatus.NotStarted)
            {
                this.analysisStartTime = DateTime.UtcNow.ToUniversalTime();
            }
        }
        public AnalysisScheduler(
            ILogProvider logProvider,
            IStoreProvider storeProvider,
            ITaskRunner taskRunner,
            TraceStoreConnection traceStoreConnection,
            CancellationToken token)
        {
            Assert.IsNotNull(logProvider, "Log Provider can't be null");
            Assert.IsNotNull(storeProvider, "Store Provider can't be null");
            Assert.IsNotNull(taskRunner, "Task Runner can't be null");
            Assert.IsNotNull(traceStoreConnection, "Trace store connection can't be null");

            this.Logger      = logProvider.CreateLoggerInstance(TracePrefix);
            this.TaskRunner  = taskRunner;
            this.consumerMap = new Dictionary <AgentIdentifier, IDictionary <IAnalysisConsumer, ConsumeOptions> >();
            this.CancelToken = token;

            // The in memory Caches for typed objects
            this.signalWaitingToBeProcessedMap = new ConcurrentDictionary <Guid, ConcurrentQueue <ScenarioData> >();

            this.analysisMetadataObjectStore = new TypedObjectStore <AnalysisMetadata>(
                this.Logger,
                storeProvider,
                AgentConstants.AnalysisMetadataStoreId,
                AgentConstants.AnalysisMetadataStoreRetentionPolicy,
                token);

            this.analysisContainerObjectStore = new TypedObjectStore <AnalysisContainer>(
                this.Logger,
                storeProvider,
                AgentConstants.AnalysisContainerStoreId,
                AgentConstants.AnalysisContainerStoreRetentionPolicy,
                token);

            this.signalWaitingToBeProcessedStoreInstance = storeProvider.CreatePersistentStoreKeyGuidValueStringAsync(
                AgentConstants.AnalysisUnprocessedSignalStoreId,
                AgentConstants.AnalysisUnprocessedSignalStoreRetentionPolicy,
                this.CancelToken).GetAwaiter().GetResult();

            Assert.IsNotNull(this.signalWaitingToBeProcessedStoreInstance, "signalWaitingToBeProcessedStoreInstance");

            // Restore state from any of the previous Runs.
            this.RestoreStateFromPreviousRunsAsync().GetAwaiter().GetResult();

            this.Logger.LogMessage("kicking off Activation Task");
            var activationTask = this.TaskRunner.Run("AgentActivationTask", this.ActivateAnalysisAsync, this.CancelToken);

            this.InitializeDataFlowPipeline();
        }
Exemple #21
0
        /// <inheritdoc />
        /// <remarks>
        /// You can add the same routine again and we will call you once for each registered callback. Caller should handle that logic
        /// </remarks>
        public async Task RegisterCallbackAsync(NotifyFilter filter, Func <ScenarioData, Task> callbackRoutine, CancellationToken token)
        {
            Assert.IsNotNull(filter, "filter");
            Assert.IsNotNull(callbackRoutine, "callbackRoutine");

            this.Logger.LogMessage("RegisterCallbackAsync:: Registering callback with Filter '{0}'", filter);

            if (!this.GetCallbackSupportedScenario().Contains(filter.TargetScenario))
            {
                throw new NotSupportedException(
                          string.Format(CultureInfo.InvariantCulture, "Scenario : '{0}' not supported for callback", filter.TargetScenario));
            }

            await this.singleAccessLock.WaitAsync(token).ConfigureAwait(false);

            try
            {
                if (!this.callbackMap.ContainsKey(filter))
                {
                    this.callbackMap[filter] = new List <Func <ScenarioData, Task> > {
                        callbackRoutine
                    };
                }
                else
                {
                    this.callbackMap[filter].Add(callbackRoutine);
                }

                if (this.newEventSearcherTask == null)
                {
                    this.Logger.LogMessage("RegisterCallbackAsync:: Kicking off Searcher Task");

                    // kick off tasks that continuously monitors for new signals.
                    this.newEventSearcherTask = this.taskRunner.Run("NewEventSearcherTask", () => this.SearchForNewSignalsInClusterAsync(token), this.InternalTokenSource.Token);
                }

                if (this.eventDispatcherTask == null)
                {
                    this.Logger.LogMessage("RegisterCallbackAsync:: Kicking off Dispatcher Task");

                    // kick off a task that continuously looks for new signals seen and invoke callbacks associated with them.
                    this.eventDispatcherTask = this.taskRunner.Run("CallbackDispatcherTask", () => this.DispatchSignalsAsync(token), this.InternalTokenSource.Token);
                }
            }
            finally
            {
                this.singleAccessLock.Release();
            }
        }
        /// <summary>
        /// Extract the cluster Entity from
        /// </summary>
        /// <param name="fabricEvent"></param>
        /// <returns></returns>
        private BaseEntity ExtractClusterEntityFromSignal(TraceRecord fabricEvent)
        {
            Assert.IsNotNull(fabricEvent);

            BaseEntity baseEntity;

            if (!ClusterEntityExtractor.TryExtractClusterEntity(this.Logger, this.ClusterQueryInstance, fabricEvent, this.InsightLocalToken, out baseEntity))
            {
                this.Logger.LogWarning("ExtractClusterEntityFromSignal:: Couldn't Find Matching Cluster Entity for Event: '{0}'.", fabricEvent);

                return(null);
            }

            return(baseEntity);
        }
        /// <summary>
        /// Check if current filter matches this event.
        /// </summary>
        /// <param name="fabricEvent"></param>
        /// <returns></returns>
        public bool IsMatch(TraceRecord fabricEvent)
        {
            Assert.IsNotNull(fabricEvent, "traceRecord");
            if (this.traceRecord != null)
            {
                return(this.traceRecord.Equals(fabricEvent));
            }

            if (this.interestingScenario == Scenario.Reconfiguration)
            {
                var reconfigEvent = fabricEvent as ReconfigurationCompletedTraceRecord;
                return(reconfigEvent != null && reconfigEvent.PartitionId == this.partitionId);
            }

            return(false);
        }
        /// <summary>
        /// Add a Consumer
        /// </summary>
        /// <param name="analysisConsumer">Consumer</param>
        /// <param name="option">Consuming options.</param>
        public void AddConsumer(IAnalysisConsumer analysisConsumer, ConsumeOptions option)
        {
            Assert.IsNotNull(analysisConsumer, "analysisConsumer");
            var signalTriggeredAgents = this.GetSignalTriggeredAgents();

            if (signalTriggeredAgents == null)
            {
                return;
            }

            foreach (var oneAgent in signalTriggeredAgents)
            {
                this.Logger.LogMessage("AddConsumer:: Agent: {0}, Adding Consumer: {1} with Option: {2}", oneAgent, analysisConsumer.GetType(), option);
                this.analysisScheduler.AddConsumer(oneAgent, analysisConsumer, option);
            }
        }
Exemple #25
0
        public AnalysisContainer(FabricAnalysisEvent analysisEvent, AgentIdentifier agentIdentifier, int maxAnalysisAttempts = DefaultAnalysisAttempts)
        {
            if (maxAnalysisAttempts <= 0 || maxAnalysisAttempts > MaxAnalysisAttempts)
            {
                throw new ArgumentOutOfRangeException(
                          "maxAnalysisAttempts",
                          string.Format(CultureInfo.InvariantCulture, "Maximum Analysis attempt count is : '{0}'", MaxAnalysisAttempts));
            }

            Assert.IsNotNull(analysisEvent, "analysisEvent != null");
            this.AnalysisEvent      = analysisEvent;
            this.maxAttempts        = maxAnalysisAttempts;
            this.analysisOutput     = new StringBuilder();
            this.rootCauseContainer = new RootCauseContainer();
            this.fixContainer       = new FixContainer();
            this.relevantTraces     = new List <TraceRecord>();
            this.customContext      = new Dictionary <string, string>();
            this.Agent = agentIdentifier;
        }
        /// <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()));
        }
        internal void AddConsumer(AgentIdentifier agentIdentifier, IAnalysisConsumer analysisConsumer, ConsumeOptions option)
        {
            Assert.IsNotNull(analysisConsumer, "analysisConsumer");
            if (this.consumerMap.ContainsKey(agentIdentifier))
            {
                var consumersForThisAgent = this.consumerMap[agentIdentifier];
                if (consumersForThisAgent.Contains(new KeyValuePair <IAnalysisConsumer, ConsumeOptions>(analysisConsumer, option)))
                {
                    throw new Exception(string.Format(CultureInfo.InvariantCulture, "Consumer: {0} with Option: {1} Already Present", analysisConsumer, option));
                }

                consumersForThisAgent[analysisConsumer] = option;
            }
            else
            {
                this.consumerMap[agentIdentifier] = new Dictionary <IAnalysisConsumer, ConsumeOptions> {
                    { analysisConsumer, option }
                };
            }
        }
Exemple #28
0
        /// <inheritdoc />
        public async Task UnRegisterCallbackAsync(NotifyFilter filter, Func <ScenarioData, Task> callbackRoutine, CancellationToken token)
        {
            Assert.IsNotNull(filter, "filter");
            Assert.IsNotNull(callbackRoutine, "callbackRoutine");
            this.Logger.LogMessage("UnRegisterCallbackAsync:: UnRegistering callback with Filter '{0}'", filter);

            if (!this.GetCallbackSupportedScenario().Contains(filter.TargetScenario))
            {
                throw new NotSupportedException(
                          string.Format(CultureInfo.InvariantCulture, "Scenario : '{0}' not supported for callback", filter.TargetScenario));
            }

            await this.singleAccessLock.WaitAsync(token).ConfigureAwait(false);

            try
            {
                if (!this.callbackMap.ContainsKey(filter))
                {
                    throw new CallbackNotRegisteredException(string.Format(CultureInfo.InvariantCulture, "Callback for Filter: {0} not registered", filter));
                }

                if (!this.callbackMap[filter].Contains(callbackRoutine))
                {
                    throw new CallbackNotRegisteredException(
                              string.Format(CultureInfo.InvariantCulture, "Callback for Filter: {0} with Delegage: {1} not registered", filter, callbackRoutine));
                }

                this.callbackMap[filter].Remove(callbackRoutine);

                // if there are no callbacks for this filter, remove the entry from map.
                if (!this.callbackMap[filter].Any())
                {
                    this.callbackMap[filter] = null;
                    this.callbackMap.Remove(filter);
                }
            }
            finally
            {
                this.singleAccessLock.Release();
            }
        }
        private async Task KickOffAnalysisAsync(AnalysisContainer analysis)
        {
            await this.PreAnalysisActionsAsync(analysis).ConfigureAwait(false);

            this.CancelToken.ThrowIfCancellationRequested();

            var key = analysis.GetUniqueIdentity();

            var schedulingInfo = (await this.analysisMetadataObjectStore.GetTypedObjectAsync(key)).SchedulingInfo;

            Continuation          continuation = null;
            ExceptionDispatchInfo dispatchInfo = null;

            try
            {
                Assert.IsNotNull(AgentDirectory.SingleInstance, "AgentDirectory.SingleInstance != null");
                var agent = AgentDirectory.SingleInstance.GetOrCreateAgentInstance(analysis.Agent);

                if (schedulingInfo.GetContinuationType() == ContinuationType.WaitForInterest)
                {
                    this.Logger.LogMessage("KickOffAnalysisAsync:: Launching Update. Key : {0}", key);
                    continuation = await agent.UpdateAnalysisAsync(analysis).ConfigureAwait(false);
                }
                else
                {
                    this.Logger.LogMessage("KickOffAnalysisAsync:: Calling Main Analysis. Key : {0}", key);
                    continuation = await agent.DoAnalysisAsync(analysis).ConfigureAwait(false);
                }

                this.Logger.LogMessage("KickOffAnalysisAsync:: Continuation : {0} Analysis {1}, key: {2}", continuation, analysis, key);
            }
            catch (Exception exp)
            {
                this.Logger.LogMessage("KickOffAnalysisAsync:: Exception {0} Encountered while Analysing Container: {1}", exp, analysis);
                dispatchInfo = ExceptionDispatchInfo.Capture(exp);
            }

            await this.PostAnalysisActionsAsync(analysis, continuation, dispatchInfo).ConfigureAwait(false);
        }
        /// <inheritdoc />
        public override 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)));

            if (reconfig.TotalDurationMs > this.currentConfig.ReconfigTimeThresholdForAnalysis.TotalMilliseconds)
            {
                return(Task.FromResult(true));
            }

            if (reconfig.Result != ReconfigurationResult.Completed)
            {
                return(Task.FromResult(true));
            }

            return(Task.FromResult(true));
        }