private async Task <int> FillCabinetDrawerAsync(CosmosCabinetDrawer drawer, IEnumerable <DataAvailableNotification> notifications) { var count = 0; var tasks = notifications.Select(async x => { if (await CheckIdempotencyAsync(x).ConfigureAwait(false)) { return; } var cosmosDataAvailable = CosmosDataAvailableMapper.Map(x, drawer.Id); await _repositoryContainer .Cabinet .CreateItemAsync(cosmosDataAvailable) .ConfigureAwait(false); Interlocked.Increment(ref count); }); await Task.WhenAll(tasks).ConfigureAwait(false); return(count); }
public async Task SaveAsync(CabinetKey key, IReadOnlyList <DataAvailableNotification> notifications) { ArgumentNullException.ThrowIfNull(key, nameof(key)); ArgumentNullException.ThrowIfNull(notifications, nameof(notifications)); var nextDrawer = await FindExistingDrawerWithFreeSpaceAsync(key).ConfigureAwait(false); var nextDrawerItemCount = nextDrawer != null ? await CountItemsInDrawerAsync(nextDrawer).ConfigureAwait(false) : 0; for (var i = 0; i < notifications.Count; i++) { var notification = notifications[i]; Debug.Assert(key == new CabinetKey(notification), "All notifications should belong to the provided key."); if (await CheckIdempotencyAsync(notification).ConfigureAwait(false)) { continue; } if (nextDrawer is null) { nextDrawer = CreateEmptyDrawer(notification); nextDrawerItemCount = 0; await _repositoryContainer .Cabinet .CreateItemAsync(nextDrawer) .ConfigureAwait(false); } if (nextDrawer.Position == nextDrawerItemCount) { var catalogEntry = CreateCatalogEntry(notification); await _repositoryContainer .Catalog .CreateItemAsync(catalogEntry) .ConfigureAwait(false); } var cosmosDataAvailable = CosmosDataAvailableMapper.Map(notification, nextDrawer.Id); await _repositoryContainer .Cabinet .CreateItemAsync(cosmosDataAvailable) .ConfigureAwait(false); var itemsLeft = notifications.Count - (i + 1); var spaceLeft = MaximumCabinetDrawerItemCount - (nextDrawerItemCount + 1); var itemsToFill = notifications .Skip(i + 1) .Take(Math.Min(itemsLeft, spaceLeft)); var itemsInserted = await FillCabinetDrawerAsync(nextDrawer, itemsToFill).ConfigureAwait(false); i += itemsInserted; nextDrawerItemCount += itemsInserted; nextDrawerItemCount++; Debug.Assert(nextDrawerItemCount <= MaximumCabinetDrawerItemCount, "Too many items were inserted into a single drawer."); if (nextDrawerItemCount == MaximumCabinetDrawerItemCount) { nextDrawer = null; } } }