public ScenarioNotificationData(ScenarioData scenarioData, NotifyFilter filter) { Assert.IsNotNull(scenarioData, "scenarioData"); Assert.IsNotNull(filter, "filter"); this.ScenarioData = scenarioData; this.Filter = filter; }
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)); } }
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)); } }
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; }
internal void AddExceptionSeen(Exception exp) { Assert.IsNotNull(exp); if (this.exceptionEncountered == null) { this.exceptionEncountered = new List <string>(); } }
/// <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; }
// 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); }
/// <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(); } }
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(); }
/// <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); } }
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 } }; } }
/// <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)); }
/// <summary> /// TODO: Persist time the Object was first created. That will be insight start time. /// </summary> /// <param name="insightRuntime"></param> /// <param name="token"></param> protected BaseInsightGenerator(IInsightRuntime insightRuntime, ICallbackStore callbackStore, CancellationToken token) { Assert.IsNotNull(insightRuntime, "Runtime can't be null"); Assert.IsNotNull(callbackStore, "Callback store can't be null"); this.InsightRuntime = insightRuntime; this.Logger = this.InsightRuntime.GetLogProvider().CreateLoggerInstance(this.GetType().ToString().Split('.').Last()); this.CallbackStore = callbackStore; // Since we may launch a task that we need to cancel, we go ahead create a linked token. // Any launched task will respect this linked entity. So effectively, we can chose to cancel it, // as well as the creator of this class. this.InternalTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token); this.InsightLocalToken = this.InternalTokenSource.Token; this.ClusterQueryInstance = this.InsightRuntime.GetService(typeof(IClusterQuery)) as IClusterQuery; Assert.IsNotNull(this.ClusterQueryInstance, "Runtime doesn't have a valid ClusterQuery object"); this.EntityStore = this.InsightRuntime.GetStoreProvider() .CreatePersistentStoreForStringsAsync(this.GetType() + "_EntityStore", AgeBasedRetentionPolicy.OneMonth, this.InsightLocalToken).GetAwaiter().GetResult(); this.analysisScheduler = (AnalysisScheduler)this.InsightRuntime.GetService(typeof(AnalysisScheduler)); Assert.IsNotNull(this.analysisScheduler, "AnalysisScheduler can't be null"); }
public static bool TryExtractClusterEntity( ILogger logger, IClusterQuery clusterQuery, TraceRecord traceRecord, CancellationToken cancelToken, out BaseEntity extractedEntity) { Assert.IsNotNull(clusterQuery); Assert.IsNotNull(traceRecord); extractedEntity = null; try { extractedEntity = ExtractClusterEntity(logger, clusterQuery, traceRecord, cancelToken); } catch (Exception exp) { logger.LogWarning("TryExtractClusterEntity:: Couldn't Extract Entity for Event: '{0}'. Exp: '{1}'", traceRecord, exp); return(false); } return(true); }
private async Task StopSignalTriggeredAgentsAsync(StopOptions stopOptions) { var signalTriggeredAgents = this.GetSignalTriggeredAgents(); if (signalTriggeredAgents == null || !signalTriggeredAgents.Any()) { return; } // Unregister the callbacks we have registered. Assert.IsNotNull(AgentDirectory.SingleInstance, "AgentDirectory.SingleInstance != null"); foreach (var singleFilter in signalTriggeredAgents.SelectMany(agentIdentifier => AgentDirectory.SingleInstance.GetOrCreateAgentInstance(agentIdentifier).NotifyFilters)) { this.Logger.LogMessage("StopSignalTriggeredAgentsAsync:: UnRegistering callback for scenario : '{0}'", singleFilter); await this.CallbackStore.UnRegisterCallbackAsync(singleFilter, this.HandleIncomingEventNotificationAsync, this.InsightLocalToken).ConfigureAwait(false); } // Convey stop intention to each agent. foreach (var oneAgentIdentifier in signalTriggeredAgents) { this.Logger.LogMessage("StopSignalTriggeredAgentsAsync:: Stopping Agent: '{0}'", oneAgentIdentifier); await AgentDirectory.SingleInstance.GetOrCreateAgentInstance(oneAgentIdentifier).StopAsync(stopOptions).ConfigureAwait(false); } }
/// <summary> /// Register interest in an Event /// </summary> /// <param name="traceRecord"></param> public InterestFilter RegisterInterestForEvent(TraceRecord traceRecord) { Assert.IsNotNull(traceRecord, "traceRecord"); this.traceRecord = traceRecord; return(this); }