/// <summary> /// Start Cluster Analysis /// </summary> /// <remarks> /// This abstraction get Invoked when User calls the rest API to Start Analysis. /// </remarks> /// <param name="configuration">The start configuration</param> /// <param name="token"></param> /// <returns></returns> public Task StartClusterAnalysisAsync(ClusterAnalysisConfiguration configuration, CancellationToken token) { ReleaseAssert.AssertIfNull(configuration, "configuration"); // Please note - since this is a user call, the end user call parameter value is true. return(this.StartClusterAnalysisInternalAsync(endUserCall: true, configuration: configuration, token: token)); }
private Task PersistCurrentConfigurationAsync(ClusterAnalysisConfiguration configuration, CancellationToken token) { return(this.clusterAnalyzerApiStateStore.SetEntityAsync( ClusterAnalysisApiStateStoreLaunchConfigKey, JsonConvert.SerializeObject(configuration, this.serializationSettings), token)); }
private async Task StartClusterAnalysisInternalAsync(bool endUserCall, ClusterAnalysisConfiguration configuration, CancellationToken token) { await this.startStopApiSingleAccessLock.WaitAsync(token).ConfigureAwait(false); try { var currentState = await this.GetCurrentStatusAsync(token).ConfigureAwait(false); // We skip the current state check if it is "not" an end user call. This is to cover scenario like process crash // where internal data structure may not have been updated to reflect stopped status and the new primary calls // this start again. TODO: Think of better of supporting this scenario. if (endUserCall && currentState.CurrentState == FeatureState.Running) { this.logger.LogMessage("Analysis is already Running. Please Call Stop and then start."); throw new Exception("TODO ::: Analysis is already Running. Please Call Stop and then start"); } // Create a linked token source. this.stopCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token); var runtime = await this.CreateRunTimeAsync(configuration, this.stopCancellationTokenSource.Token).ConfigureAwait(false); this.runner = new ClusterAnalysisRunner(runtime.GetLogProvider()); await this.runner.StartClusterAnalysisAsync( runtime, new List <IAnalysisConsumer> { new TraceAnalysisConsumer() }, this.stopCancellationTokenSource.Token); // Persist the current Configuration. await this.PersistCurrentConfigurationAsync(configuration, token); // If this was called by end user, we update the user intention. if (endUserCall) { currentState.UserDesiredState = FeatureState.Running; } currentState.CurrentState = FeatureState.Running; await this.PersisteCurrentStatusAsync(currentState, token); } catch (Exception exp) { // Currently, for Preview, We swallow the Exception. This ensures we don't crash FAS. this.logger.LogError("Cluster Analysis Launch Failed. Exception Encountered : {0}", exp.ToString()); } finally { this.startStopApiSingleAccessLock.Release(); } }
private Config CreateOneBoxConfig(ClusterAnalysisConfiguration configuration) { return(new Config { RunMode = RunMode.OneBoxCluster, RuntimeContext = new RuntimeContext { FabricCodePath = FabricEnvironment.GetCodePath(), FabricDataRoot = FabricEnvironment.GetDataRoot(), FabricLogRoot = FabricEnvironment.GetLogRoot() }, IsCrashDumpAnalysisEnabled = false, CrashDumpAnalyzerServiceName = string.Empty, NamedConfigManager = this.PopulateConfigurationManager(configuration) }); }
private async Task <IInsightRuntime> CreateRunTimeAsync(ClusterAnalysisConfiguration configuration, CancellationToken token) { this.logger.LogMessage("CreateRunTimeAsync:: Entering"); IInsightRuntime runtime; var isOneBox = await this.IsCurrentDeploymentOneboxAsync(token).ConfigureAwait(false); if (isOneBox) { var config = this.CreateOneBoxConfig(configuration); this.logger.LogMessage("OneBoxConfig: {0}", config); runtime = DefaultInsightRuntime.GetInstance( ClusterAnalysisLogProvider.LogProvider, PersistentStoreProvider.GetStateProvider(this.stateManager), config, new PerformanceSessionManager(ClusterAnalysisLogProvider.LogProvider, token), new TaskRunner(ClusterAnalysisLogProvider.LogProvider, this.OnUnhandledExceptionInAnalysisAsync), token); this.AddServiceToRuntime(runtime, typeof(FabricClient), this.fabricClient); this.AddServiceToRuntime(runtime, typeof(IClusterQuery), ClusterQuery.CreateClusterQueryInstance(runtime)); this.AddServiceToRuntime(runtime, typeof(IResolveServiceEndpoint), new ResolveServiceEndpoint(ServicePartitionResolver.GetDefault())); var localStoreConnection = new LocalTraceStoreConnectionInformation( runtime.GetCurrentConfig().RuntimeContext.FabricDataRoot, runtime.GetCurrentConfig().RuntimeContext.FabricLogRoot, runtime.GetCurrentConfig().RuntimeContext.FabricCodePath); this.AddServiceToRuntime( runtime, typeof(TraceStoreConnectionInformation), localStoreConnection); } else { this.logger.LogMessage("CreateRunTimeAsync:: Only One-Box deployment supported currently"); throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cluster Analysis is only supported on One-Box deployment for Preview.")); } return(runtime); }
private NamedConfigManager PopulateConfigurationManager(ClusterAnalysisConfiguration configuration) { var configManagerData = configuration.AgentConfiguration.ToDictionary(oneConfig => oneConfig.AgentName, oneConfig => oneConfig.AgentContext); return(new NamedConfigManager(configManagerData)); }