예제 #1
0
        public async Task <Counter> ProcessRequestAsync(ThrottlerItem throttlerItem, ThrottleRule rule, CancellationToken cancellationToken)
        {
            Counter counter;

            using (await _asyncLock.WriterLockAsync(throttlerItem.GenerateCounterKey()))
            {
                var entry = await _counterStore.GetAsync(throttlerItem, cancellationToken);

                if (entry.HasValue)
                {
                    // entry has not expired
                    if (entry.Value.Timestamp + rule.TimeWindow >= _systemClock.UtcNow)
                    {
                        // increment request count
                        var totalCount = entry.Value.Count + 1;

                        counter = new Counter(entry.Value.Timestamp, totalCount);
                    }
                    else
                    {
                        counter = new Counter(_systemClock.UtcNow, 1);
                    }
                }
                else
                {
                    counter = new Counter(_systemClock.UtcNow, 1);
                }

                await _counterStore.SetAsync(throttlerItem, counter, rule.TimeWindow, cancellationToken);
            }

            return(counter);
        }
예제 #2
0
        public async Task <IEnumerable <Event> > ProcessAsync(Event evnt)
        {
            var notYetAccountedFor = evnt.GetBody <OrderItemsNotYetAccountedFor>();
            var keyValue           = notYetAccountedFor.ProductQuantities.First();
            var productId          = keyValue.Key;
            var quantity           = keyValue.Value;


            var inventory = await _inventoryStore.GetAsync(Constants.InventoryCounterName, productId);

            var events = new List <Event>();

            // remove item since it will be dealt with
            notYetAccountedFor.ProductQuantities.Remove(keyValue.Key);


            // if out of stock, raise out of stock
            if (quantity > inventory)
            {
                Trace.TraceInformation("OrderItemInventoryActor - Item out of stock");

                events.Add(new Event(new ProductOutOfStock()
                {
                    ProductId = productId,
                    Quantity  = keyValue.Value
                }));

                events.Add(new Event(new ItemOutOfStockForOrder()
                {
                    OrderId   = notYetAccountedFor.OrderId,
                    ProductId = productId,
                    Quantity  = quantity
                }));

                notYetAccountedFor.AnyOutOfStock = true;
            }
            else
            {
                // decrement repo
                await _inventoryStore.IncrementAsync(Constants.InventoryCounterName,
                                                     productId, -quantity);

                Trace.TraceInformation("OrderItemInventoryActor - Item in stock");
            }

            if (notYetAccountedFor.ProductQuantities.Count > 0)
            {
                // put back in the queue
                events.Add(new Event(new OrderItemsNotYetAccountedFor()
                {
                    OrderId           = notYetAccountedFor.OrderId,
                    AnyOutOfStock     = notYetAccountedFor.AnyOutOfStock,
                    ProductQuantities = notYetAccountedFor.ProductQuantities
                }));
            }


            if (notYetAccountedFor.ProductQuantities.Count == 0)
            {
                if (notYetAccountedFor.AnyOutOfStock)
                {
                    // TODO: cant remember what needs to be done ;)
                }
                else
                {
                    events.Add(new Event(new OrderInventoryCheckCompleted()
                    {
                        OrderId = notYetAccountedFor.OrderId
                    }));
                }
            }

            return(events);
        }