Exemple #1
0
        public async Task Consume(ConsumeContext <BookStock> context)
        {
            await EnsureBaseCreatedAsync();

            var id       = context.CorrelationId.GetValueOrDefault();
            var quantity = context.Message.Quantity;

            logger.LogInformation($"Received {nameof(BookStock)} message with Id = '{id}' and Quantity = {quantity}.");

            var couldEnterSemaphore = await locker.WaitAsync(TimeSpan.FromSeconds(30));

            if (!couldEnterSemaphore)
            {
                logger.LogError($"Technical Error : couldn't enter thread-safe area.");

                await context.Publish <StockBookingFailed>(new { context.CorrelationId });

                return;
            }

            var stock = await dbContext.Stocks.FirstOrDefaultAsync();

            if (stock is null || stock.Quantity < quantity)
            {
                logger.LogInformation($"Not enough stock left.");

                await context.Publish <StockBookingFailed>(new { context.CorrelationId });

                locker.Release();

                return;
            }

            logger.LogInformation($"'{stock.Quantity}' left in stock. Removing {quantity}.");

            stock.Quantity -= quantity;

            dbContext.StockBookings.Add(new StockBooking {
                Quantity = quantity, Id = id
            });

            await dbContext.SaveChangesAsync();

            await context.Publish <StockBooked>(new { context.CorrelationId });

            locker.Release();
        }
Exemple #2
0
        public async Task Consume(ConsumeContext <UnbookStock> context)
        {
            await EnsureBaseCreatedAsync();

            var id       = context.CorrelationId.GetValueOrDefault();
            var quantity = context.Message.Quantity;

            logger.LogInformation($"Received {nameof(UnbookStock)} message with Id = '{id}' and Quantity = {quantity}.");

            var couldEnterSemaphore = await locker.WaitAsync(TimeSpan.FromSeconds(30));

            if (!couldEnterSemaphore)
            {
                logger.LogError($"Technical Error : couldn't enter thread-safe area. Will retry.");

                throw new Exception();
            }

            var stock = await dbContext.Stocks.FirstAsync();

            var booking = await dbContext.StockBookings.FindAsync(id);

            if (booking is null)
            {
                logger.LogInformation($"No booking find with Id = '{id}'. Skipping.");

                locker.Release();

                return;
            }

            dbContext.StockBookings.Remove(booking);

            logger.LogInformation($"'{stock.Quantity}' left in stock. Adding {quantity} back.");

            stock.Quantity += quantity;

            await dbContext.SaveChangesAsync();

            locker.Release();
        }