Beispiel #1
0
        private async Task ProcessBatchesAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                _logger.LogInformation($"Sleeping for {_configuration.BatchFrequencyInMilliseconds} ms.".AddTimestamp());
                await Task.Delay(_configuration.BatchFrequencyInMilliseconds, cancellationToken);

                List <Bet> batch;
                ulong      deliveryTag;
                lock (_betsBatch)
                {
                    batch       = _betsBatch;
                    _betsBatch  = new List <Bet>();
                    deliveryTag = _lastDeliveryTag;
                }

                if (!batch.Any())
                {
                    _logger.LogInformation("No batch to process.".AddTimestamp());
                    continue;
                }

                _logger.LogInformation($"Processing batch of {batch.Count} bets.".AddTimestamp());

                var stakeIds       = batch.Select(b => b.StakeId);
                var betsByStakeIds = batch.GroupBy(b => b.StakeId).ToDictionary(g => g.Key, g => g.Count());

                using (var dbContext = new BetsDbContext(_configuration.ConnectionString))
                    using (var transaction = await dbContext.Database.BeginTransactionAsync(IsolationLevel.RepeatableRead, cancellationToken))
                    {
                        var matches = await dbContext.Matches.Include(m => m.Stakes).Where(m => m.Stakes.Any(s => stakeIds.Contains(s.Id)))
                                      .ToListAsync(cancellationToken);

                        _logger.LogInformation($"Got {matches.Count} matches".AddTimestamp());

                        var newStakes = matches.SelectMany(m => m.Stakes.Where(s => s.IsBettable).Select(s => CalculateNewStake(s, m, betsByStakeIds))).ToList();

                        foreach (var oldStake in matches.SelectMany(m => m.Stakes.Where(s => s.IsBettable)))
                        {
                            oldStake.IsBettable = false;
                        }
                        _logger.LogInformation("Calculated stakes.");
                        dbContext.Stakes.AddRange(newStakes);
                        await dbContext.SaveChangesAsync(cancellationToken);

                        transaction.Commit();
                    }

                EventConsumer.Ack(deliveryTag);
            }
        }