Beispiel #1
0
        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);
        }
Beispiel #2
0
        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;
                }
            }
        }