/// <summary> /// Enumerates scheduled health checks. /// </summary> internal async Task EnumerateHealthChecksAsync() { // Check if the partition is readable/writable. if (PartitionAccessStatus.Granted != this._service.ReadStatus || PartitionAccessStatus.Granted != this._service.WriteStatus) { return; } // Get the health check schedule items. IReliableDictionary <long, WatchdogScheduledItem> scheduleDict = await this.GetHealthCheckScheduleDictionaryAsync(); // Create a transaction for the enumeration. using (ITransaction eTx = this._service.StateManager.CreateTransaction()) { // Create the AsyncEnumerator. Data.IAsyncEnumerator <KeyValuePair <long, WatchdogScheduledItem> > ae = (await scheduleDict.CreateEnumerableAsync(eTx, EnumerationMode.Ordered)).GetAsyncEnumerator(); while (await ae.MoveNextAsync(this._token)) { // Compare the times, if this item is due for execution if (ae.Current.Value.ExecutionTicks < DateTimeOffset.UtcNow.UtcTicks) { await this.PerformItemHealthCheckAsync(ae.Current.Value); } } await eTx.CommitAsync(); } this._healthState = HealthState.Ok; }
/// <summary> /// Enumerates metric requests. /// </summary> internal async Task EnumerateMetricsAsync() { // Check if the partition is readable/writable. if (PartitionAccessStatus.Granted != this._service.ReadStatus || PartitionAccessStatus.Granted != this._service.WriteStatus) { return; } // Get the health check schedule items. IReliableDictionary <string, MetricCheck> mDict = await this.GetMetricCheckDictionaryAsync(); // Create a transaction for the enumeration. using (ITransaction tx = this._service.StateManager.CreateTransaction()) { bool result = false; // Create the AsyncEnumerator. Data.IAsyncEnumerator <KeyValuePair <string, MetricCheck> > ae = (await mDict.CreateEnumerableAsync(tx, EnumerationMode.Ordered)).GetAsyncEnumerator(); while (await ae.MoveNextAsync(this._token)) { MetricCheck mc = ae.Current.Value; if ((false == string.IsNullOrWhiteSpace(mc.Service)) && (default(Guid) != mc.Partition)) { result = await this.ReportPartitionMetricAsync(mc).ConfigureAwait(false); } else if ((false == string.IsNullOrWhiteSpace(mc.Service)) && (default(Guid) == mc.Partition)) { result = await this.ReportServiceMetricAsync(mc).ConfigureAwait(false); } else { result = await this.ReportApplicationMetricAsync(mc).ConfigureAwait(false); } } } this._healthState = HealthState.Ok; }
/// <summary> /// Gets a filtered set of HealthCheck items. /// </summary> /// <param name="application">Optional application filter.</param> /// <param name="service">Optional service filter.</param> /// <param name="partition">Optional partition filter.</param> /// <returns>List containing the set of matching HealthCheck items.</returns> /// <remarks>If application is null or empty, the values passed in service and partition will be ignored. /// If service is null or empty, the values passed in partition will be ignored. /// </remarks> public async Task <IList <HealthCheck> > GetHealthChecksAsync(string application = null, string service = null, Guid?partition = null) { string filter = string.Empty; List <HealthCheck> items = new List <HealthCheck>(); // Get the required dictionaries. IReliableDictionary <string, HealthCheck> hcDict = await this.GetHealthCheckDictionaryAsync().ConfigureAwait(false); if ((false == string.IsNullOrWhiteSpace(application)) && (false == string.IsNullOrWhiteSpace(service)) && (partition.HasValue)) { filter = $"fabric:/{application}/{service}/{partition}"; } else if ((false == string.IsNullOrWhiteSpace(application)) && (false == string.IsNullOrWhiteSpace(service))) { filter = $"fabric:/{application}/{service}"; } else if (false == string.IsNullOrWhiteSpace(application)) { filter = $"fabric:/{application}"; } try { using (ITransaction tx = this._service.StateManager.CreateTransaction()) { // Query the dictionary for an order list filtered by however much the user specified. Data.IAsyncEnumerable <KeyValuePair <string, HealthCheck> > list = await hcDict.CreateEnumerableAsync(tx, (s) => { return(s.StartsWith(filter)); }, EnumerationMode.Ordered).ConfigureAwait(false); Data.IAsyncEnumerator <KeyValuePair <string, HealthCheck> > asyncEnumerator = list.GetAsyncEnumerator(); while (await asyncEnumerator.MoveNextAsync(this._token).ConfigureAwait(false)) { items.Add(asyncEnumerator.Current.Value); } } } catch (FabricObjectClosedException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.GetHealthChecksAsync)); } catch (TimeoutException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.GetHealthChecksAsync)); } catch (FabricTransientException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.GetHealthChecksAsync)); } catch (FabricException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.GetHealthChecksAsync)); } catch (Exception ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.GetHealthChecksAsync)); } // Update the cached count and return the list of HealthCheck items. Interlocked.Exchange(ref this._healthCheckCount, items.Count); return(items); }