示例#1
0
        private static async Task StartMonitoringAsync(string uri, string key, string collection, CancellationToken ctsToken)
        {
            IRemainingWorkEstimator estimator = await CreateEstimatorAsync(uri, key, collection);

            StringBuilder builder = new StringBuilder();

            while (!ctsToken.IsCancellationRequested)
            {
                builder.Clear();

                IReadOnlyList <RemainingPartitionWork> remainingWork = await estimator.GetEstimatedRemainingWorkPerPartitionAsync();

                for (int i = 0; i < remainingWork.Count; i++)
                {
                    var work = remainingWork[i];
                    if (i != 0)
                    {
                        builder.Append(",");
                    }
                    builder.AppendFormat(work.PartitionKeyRangeId + ":" + work.RemainingWork);
                }
                Console.WriteLine($"### Estimated work: {builder}");

                try
                {
                    await Task.Delay(5000, ctsToken);
                }
                catch (TaskCanceledException) { }
            }
        }
        public CosmosDBTriggerListener(ITriggeredFunctionExecutor executor,
                                       string functionId,
                                       DocumentCollectionInfo documentCollectionLocation,
                                       DocumentCollectionInfo leaseCollectionLocation,
                                       ChangeFeedProcessorOptions processorOptions,
                                       ICosmosDBService monitoredCosmosDBService,
                                       ICosmosDBService leasesCosmosDBService,
                                       ILogger logger,
                                       IRemainingWorkEstimator workEstimator = null)
        {
            this._logger     = logger;
            this._executor   = executor;
            this._functionId = functionId;
            this._hostName   = Guid.NewGuid().ToString();

            this._monitorCollection        = documentCollectionLocation;
            this._leaseCollection          = leaseCollectionLocation;
            this._processorOptions         = processorOptions;
            this._monitoredCosmosDBService = monitoredCosmosDBService;
            this._leasesCosmosDBService    = leasesCosmosDBService;
            this._healthMonitor            = new CosmosDBTriggerHealthMonitor(this._logger);

            this._workEstimator = workEstimator;

            this._scaleMonitorDescriptor = new ScaleMonitorDescriptor($"{_functionId}-CosmosDBTrigger-{_monitorCollection.DatabaseName}-{_monitorCollection.CollectionName}".ToLower());
        }
        public async Task <CosmosDBTriggerMetrics> GetMetricsAsync()
        {
            int  partitionCount = 0;
            long remainingWork  = 0;
            IReadOnlyList <RemainingPartitionWork> partitionWorkList = null;

            try
            {
                IRemainingWorkEstimator workEstimator = await GetWorkEstimatorAsync();

                partitionWorkList = await workEstimator.GetEstimatedRemainingWorkPerPartitionAsync();

                partitionCount = partitionWorkList.Count;
                remainingWork  = partitionWorkList.Sum(item => item.RemainingWork);
            }
            catch (Exception e) when(e is DocumentClientException || e is InvalidOperationException)
            {
                if (!TryHandleDocumentClientException(e))
                {
                    _logger.LogWarning("Unable to handle {0}: {1}", e.GetType().ToString(), e.Message);
                    if (e is InvalidOperationException)
                    {
                        throw;
                    }
                }
            }
            catch (System.Net.Http.HttpRequestException e)
            {
                string errormsg;

                var webException = e.InnerException as WebException;
                if (webException != null &&
                    webException.Status == WebExceptionStatus.ProtocolError)
                {
                    string statusCode = ((HttpWebResponse)webException.Response).StatusCode.ToString();
                    string statusDesc = ((HttpWebResponse)webException.Response).StatusDescription;
                    errormsg = string.Format("CosmosDBTrigger status {0}: {1}.", statusCode, statusDesc);
                }
                else if (webException != null &&
                         webException.Status == WebExceptionStatus.NameResolutionFailure)
                {
                    errormsg = string.Format("CosmosDBTrigger Exception message: {0}.", webException.Message);
                }
                else
                {
                    errormsg = e.ToString();
                }

                _logger.LogWarning(errormsg);
            }

            return(new CosmosDBTriggerMetrics
            {
                Timestamp = DateTime.UtcNow,
                PartitionCount = partitionCount,
                RemainingWork = remainingWork
            });
        }
示例#4
0
        /// <summary>
        /// Asynchronously checks the current existing leases and calculates an estimate of remaining work per leased partitions.
        /// </summary>
        /// <returns>An estimate amount of remaining documents to be processed</returns>
        public async Task <long> GetEstimatedRemainingWork()
        {
            if (this.remainingWorkEstimator == null)
            {
                this.remainingWorkEstimator = await this.builder.BuildEstimatorAsync().ConfigureAwait(false);
            }

            return(await this.remainingWorkEstimator.GetEstimatedRemainingWork().ConfigureAwait(false));
        }
        private async Task <IRemainingWorkEstimator> GetWorkEstimatorAsync()
        {
            if (_workEstimatorBuilder == null)
            {
                _workEstimatorBuilder = new ChangeFeedProcessorBuilder()
                                        .WithHostName(this._hostName)
                                        .WithFeedDocumentClient(this._monitoredCosmosDBService.GetClient())
                                        .WithLeaseDocumentClient(this._leasesCosmosDBService.GetClient())
                                        .WithFeedCollection(this._monitorCollection)
                                        .WithLeaseCollection(this._leaseCollection)
                                        .WithProcessorOptions(this._processorOptions)
                                        .WithHealthMonitor(this._healthMonitor)
                                        .WithObserverFactory(this);
            }

            if (_workEstimator == null)
            {
                _workEstimator = await _workEstimatorBuilder.BuildEstimatorAsync();
            }

            return(_workEstimator);
        }