public virtual async Task <List <BlobChangeFeedEvent> > GetPage( bool async, int?pageSize, CancellationToken cancellationToken = default) { List <BlobChangeFeedEvent> changeFeedEventList = new List <BlobChangeFeedEvent>(); if (!HasNext()) { throw new InvalidOperationException("Segment doesn't have any more events"); } int i = 0; while (i < pageSize && _shards.Count > 0) { // If this Shard is finished, skip it. if (_finishedShards.Contains(_shardIndex)) { _shardIndex++; if (_shardIndex == _shards.Count) { _shardIndex = 0; } continue; } Shard currentShard = _shards[_shardIndex]; BlobChangeFeedEvent changeFeedEvent = await currentShard.Next(async, cancellationToken).ConfigureAwait(false); changeFeedEventList.Add(changeFeedEvent); // If the current shard is completed, remove it from _shards if (!currentShard.HasNext()) { _finishedShards.Add(_shardIndex); } i++; _shardIndex++; if (_shardIndex >= _shards.Count) { _shardIndex = 0; } // If all the Shards are finished, we need to break out early. if (_finishedShards.Count == _shards.Count) { break; } } return(changeFeedEventList); }
#pragma warning disable CA1822 // Does not acces instance data can be marked static. public virtual async Task <Segment> BuildSegment( #pragma warning restore CA1822 // Can't mock static methods in MOQ. bool async, string manifestPath, SegmentCursor cursor = default) { // Models we need for later List <Shard> shards = new List <Shard>(); DateTimeOffset dateTime = BlobChangeFeedExtensions.ToDateTimeOffset(manifestPath).Value; // Download segment manifest BlobClient blobClient = _containerClient.GetBlobClient(manifestPath); BlobDownloadInfo blobDownloadInfo; if (async) { blobDownloadInfo = await blobClient.DownloadAsync().ConfigureAwait(false); } else { blobDownloadInfo = blobClient.Download(); } // Parse segment manifest JsonDocument jsonManifest; if (async) { jsonManifest = await JsonDocument.ParseAsync(blobDownloadInfo.Content).ConfigureAwait(false); } else { jsonManifest = JsonDocument.Parse(blobDownloadInfo.Content); } foreach (JsonElement shardJsonElement in jsonManifest.RootElement.GetProperty("chunkFilePaths").EnumerateArray()) { string shardPath = shardJsonElement.ToString().Substring("$blobchangefeed/".Length); var shardCursor = cursor?.ShardCursors?.Find(x => x.CurrentChunkPath.StartsWith(shardPath, StringComparison.InvariantCulture)); Shard shard = await _shardFactory.BuildShard( async, shardPath, shardCursor) .ConfigureAwait(false); if (shard.HasNext()) { shards.Add(shard); } } int shardIndex = 0; string currentShardPath = cursor?.CurrentShardPath; if (!string.IsNullOrWhiteSpace(currentShardPath)) { shardIndex = shards.FindIndex(s => s.ShardPath == currentShardPath); if (shardIndex < 0) { // Either shard doesn't exist or cursor is pointing to end of shard. So start from beginning. shardIndex = 0; } } return(new Segment( shards, shardIndex, dateTime, manifestPath)); }