private static string GetFirstItemLSN(Collection <JObject> items) { JObject item = RemainingWorkEstimatorCore.GetFirstItem(items); if (item == null) { return(null); } if (item.TryGetValue(LSNPropertyName, StringComparison.OrdinalIgnoreCase, out JToken property)) { return(property.Value <string>()); } DefaultTrace.TraceWarning("Change Feed response item does not include LSN."); return(null); }
private async Task <long> GetRemainingWorkAsync(DocumentServiceLease existingLease, CancellationToken cancellationToken) { // Current lease schema maps Token to PKRangeId string partitionKeyRangeId = existingLease.CurrentLeaseToken; using FeedIterator iterator = this.feedCreator( partitionKeyRangeId, existingLease.ContinuationToken, string.IsNullOrEmpty(existingLease.ContinuationToken)); try { ResponseMessage response = await iterator.ReadNextAsync(cancellationToken).ConfigureAwait(false); if (response.StatusCode != HttpStatusCode.NotModified) { response.EnsureSuccessStatusCode(); } long parsedLSNFromSessionToken = RemainingWorkEstimatorCore.TryConvertToNumber(ExtractLsnFromSessionToken(response.Headers[HttpConstants.HttpHeaders.SessionToken])); IEnumerable <JObject> items = RemainingWorkEstimatorCore.GetItemsFromResponse(response); long lastQueryLSN = items.Any() ? RemainingWorkEstimatorCore.TryConvertToNumber(RemainingWorkEstimatorCore.GetFirstItemLSN(items)) - 1 : parsedLSNFromSessionToken; if (lastQueryLSN < 0) { return(1); } long leaseTokenRemainingWork = parsedLSNFromSessionToken - lastQueryLSN; return(leaseTokenRemainingWork < 0 ? 0 : leaseTokenRemainingWork); } catch (Exception clientException) { Cosmos.Extensions.TraceException(clientException); DefaultTrace.TraceWarning("GetEstimateWork > exception: lease token '{0}'", existingLease.CurrentLeaseToken); throw; } }