コード例 #1
0
        public Task UpdateCountAsync(int fromStationId, int toStationId)
        {
            var stations  = StateData.Stations;
            var matchFrom = false;
            var matchTo   = false;

            foreach (var station in stations)
            {
                if (station == fromStationId)
                {
                    matchFrom = true;
                }

                if (matchFrom && station == toStationId)
                {
                    matchTo = true;
                    break;
                }
            }

            if (!matchTo)
            {
                throw new StationNotFoundException(TrainId, fromStationId, toStationId);
            }

            var evt = this.CreateEvent(new UpdateCountEvent
            {
                FromStationId = fromStationId,
                ToStationId   = toStationId
            });

            return(Claptrap.HandleEventAsync(evt));
        }
コード例 #2
0
        public async Task <int> UpdateInventoryAsync(int diff)
        {
            if (diff == 0)
            {
                throw new BizException("diff can`t be 0");
            }

            var old          = StateData.Inventory;
            var newInventory = old + diff;

            if (newInventory < 0)
            {
                throw new BizException(
                          $"failed to update inventory. It will be less than 0 if add diff amount. current : {old} , diff : {diff}");
            }

            var evt = this.CreateEvent(new InventoryUpdateEvent
            {
                Diff         = diff,
                NewInventory = newInventory
            });
            await Claptrap.HandleEventAsync(evt);

            return(StateData.Inventory);
        }
コード例 #3
0
ファイル: Burning.cs プロジェクト: xcl-net/Newbe.Claptrap
        public Task HandleOneAsync()
        {
            var evt = new UnitEvent(_identity, Codes.BurningEvent,
                                    UnitEvent.UnitEventData.Create());

            return(Claptrap.HandleEventAsync(evt));
        }
コード例 #4
0
        public async Task RunAsync(SagaFlow flow)
        {
            _ = _activated.Value;
            if (StateData.SagaFlowState != null !)
            {
                if (StateData.SagaFlowState.IsCompleted)
                {
                    _logger.LogInformation("saga flow already completed");
                    return;
                }
            }
            else
            {
                _logger.LogInformation("saga flow is not built, start to build it");
                var evt = new SagaFlowCreateEvent
                {
                    Steps           = flow.Steps,
                    CompensateSteps = flow.CompensateSteps,
                    UserData        = _sagaUserDataSerializer.Serialize(flow.UserData, flow.UserData.GetType()),
                    UserDataType    = flow.UserData.GetType()
                };

                await Claptrap.HandleEventAsync(new DataEvent(_identity, SagaCodes.Create, evt));
            }

            await ContinueAsync();
        }
コード例 #5
0
 public async Task MasterEventReceivedAsync(IEnumerable <IEvent> events)
 {
     foreach (var @event in events)
     {
         await Claptrap.HandleEventAsync(@event);
     }
 }
コード例 #6
0
        public async Task CreateOrderAsync(CreateOrderInput input)
        {
            var orderId = Claptrap.State.Identity.Id;

            // throw exception if order already created
            if (StateData.OrderCreated)
            {
                throw new BizException($"order with order id already created : {orderId}");
            }

            // get items from cart
            var cartGrain = _grainFactory.GetGrain <ICartGrain>(input.CartId);
            var items     = await cartGrain.GetItemsAsync();

            // update inventory for each sku
            foreach (var(skuId, count) in items)
            {
                var skuGrain = _grainFactory.GetGrain <ISkuGrain>(skuId);
                await skuGrain.UpdateInventoryAsync(-count);
            }

            // remove all items from cart
            await cartGrain.RemoveAllItemsAsync();

            // create a order
            var evt = this.CreateEvent(new OrderCreatedEvent
            {
                UserId = input.UserId,
                Skus   = items
            });
            await Claptrap.HandleEventAsync(evt);
        }
コード例 #7
0
        public async Task MasterEventReceivedJsonAsync(IEnumerable <EventJsonModel> events)
        {
            var items = events.Select(_eventSerializer.Deserialize);

            foreach (var @event in items)
            {
                await Claptrap.HandleEventAsync(@event);
            }
        }
コード例 #8
0
        public Task TransferIn(decimal amount, string uid)
        {
            var accountBalanceChangeEventData = new AccountBalanceChangeEventData
            {
                Diff = +amount
            };
            var dataEvent = this.CreateEvent(accountBalanceChangeEventData);

            return(Claptrap.HandleEventAsync(dataEvent));
        }
コード例 #9
0
ファイル: Account.cs プロジェクト: xcl-net/Newbe.Claptrap
        public Task ChangeBalanceAsync(decimal diff)
        {
            var evt = new AccountBalanceChangeEvent
            {
                Diff = diff,
            };

            return(Claptrap.HandleEventAsync(new DataEvent(Claptrap.State.Identity, Codes.AccountBalanceChangeEvent,
                                                           evt)));
        }
コード例 #10
0
        public async Task <ArticleData> UpdateAsync(ArticleData articleData)
        {
            var dataEvent = this.CreateEvent(new UpdateArticleEventData
            {
                ArticleData = articleData
            });
            await Claptrap.HandleEventAsync(dataEvent);

            return(StateData.Current);
        }
コード例 #11
0
        public async Task <Dictionary <string, int> > RemoveItemAsync(string skuId, int count)
        {
            var evt = this.CreateEvent(new RemoveItemFromCartEvent
            {
                Count = count,
                SkuId = skuId
            });
            await Claptrap.HandleEventAsync(evt);

            return(StateData.Items);
        }
コード例 #12
0
        public void RunReflection()
        {
            var claptrap = new Claptrap();

            for (int i = 0; i < Count; i++)
            {
                _methodInfo.Invoke(claptrap, new[] { (object)Diff });
            }

            claptrap.Level.Should().Be(Count * Diff);
        }
コード例 #13
0
        public void RunExpression()
        {
            var claptrap = new Claptrap();

            for (int i = 0; i < Count; i++)
            {
                _func.Invoke(claptrap, Diff);
            }

            claptrap.Level.Should().Be(Count * Diff);
        }
コード例 #14
0
        public void Directly()
        {
            var claptrap = new Claptrap();

            for (int i = 0; i < Count; i++)
            {
                claptrap.LevelUp(Diff);
            }

            claptrap.Level.Should().Be(Count * Diff);
        }
コード例 #15
0
        public Task RemoveAllItemsAsync()
        {
            if (StateData.Items?.Any() != true)
            {
                return(Task.CompletedTask);
            }

            var removeAllItemsFromCartEvent = new RemoveAllItemsFromCartEvent();
            var evt = this.CreateEvent(removeAllItemsFromCartEvent);

            return(Claptrap.HandleEventAsync(evt));
        }
コード例 #16
0
        public void RunReflection()
        {
            var claptrap = new Claptrap();

            for (int i = 0; i < Count; i++)
            {
                var value = (int)_propertyInfo.GetValue(claptrap);
                _propertyInfo.SetValue(claptrap, value + Diff);
            }

            claptrap.Level.Should().Be(Count * Diff);
        }
コード例 #17
0
        public async Task <decimal> TransferInAsync(decimal amount)
        {
            var accountBalanceChangeEventData = new AccountBalanceChangeEventData
            {
                Diff = +amount
            };
            var dataEvent = this.CreateEvent(accountBalanceChangeEventData);
            await Claptrap.HandleEventAsync(dataEvent);

            var re = await GetBalanceAsync();

            return(re);
        }
コード例 #18
0
        public Task TakeSeatAsync(int fromStationId, int toStationId, string requestId)
        {
            if (!StateData.StationDic.TryGetValue(fromStationId, out var fromIndex))
            {
                throw CreateNotFoundException();
            }

            if (!StateData.StationDic.TryGetValue(toStationId, out var toIndex))
            {
                throw CreateNotFoundException();
            }

            if (fromIndex >= toIndex)
            {
                throw CreateNotFoundException();
            }

            var distance     = toIndex - fromIndex;
            var notRequested = StateData.RequestIds
                               .Skip(fromIndex)
                               .Take(distance)
                               .All(string.IsNullOrEmpty);

            if (!notRequested)
            {
                throw new SeatHasBeenTakenException(SeatId,
                                                    fromStationId,
                                                    toStationId);
            }

            var evt = this.CreateEvent(new TakeSeatEvent
            {
                RequestId     = requestId,
                FromStationId = fromStationId,
                ToStationId   = toStationId
            });

            return(Claptrap.HandleEventAsync(evt));

            StationNotFoundException CreateNotFoundException()
            {
                var seatId = Main.SeatId.FromSeatId(SeatId);

                return(new StationNotFoundException(seatId.TrainId,
                                                    fromStationId,
                                                    toStationId));
            }
        }
コード例 #19
0
 public SagaClaptrap(IClaptrapIdentity identity,
                     IClaptrapFactory claptrapFactory,
                     IClaptrapAccessor claptrapAccessor,
                     ISagaUserDataSerializer sagaUserDataSerializer,
                     ILogger <SagaClaptrap> logger) : base(identity,
                                                           claptrapFactory,
                                                           claptrapAccessor)
 {
     _identity = identity;
     _sagaUserDataSerializer = sagaUserDataSerializer;
     _logger    = logger;
     _activated = new Lazy <bool>(() =>
     {
         Claptrap.ActivateAsync().Wait();
         return(true);
     });
 }
コード例 #20
0
        public Task <TryBiddingResult> TryBidding(TryBiddingInput input)
        {
            var status = GetStatusCore();

            if (status != AuctionItemStatus.OnSell)
            {
                return(Task.FromResult(CreateResult(false)));
            }

            if (input.Price <= GetTopPrice())
            {
                return(Task.FromResult(CreateResult(false)));
            }

            return(HandleCoreAsync());

            async Task <TryBiddingResult> HandleCoreAsync()
            {
                var dataEvent = this.CreateEvent(new NewBidderEvent
                {
                    Price  = input.Price,
                    UserId = input.UserId
                });
                await Claptrap.HandleEventAsync(dataEvent);

                return(CreateResult(true));
            }

            TryBiddingResult CreateResult(bool success)
            {
                return(new()
                {
                    Success = success,
                    NowPrice = GetTopPrice(),
                    UserId = input.UserId,
                    AuctionItemStatus = status
                });
            }

            decimal GetTopPrice()
            {
                return(StateData.BiddingRecords?.Any() == true
                    ? StateData.BiddingRecords.First().Key
                    : StateData.BasePrice);
            }
        }
コード例 #21
0
        public async Task <string> LoginAsync(string username, string password)
        {
            var userInfo     = StateData;
            var hashPassword = PasswordHelper.HashPassword(userInfo.Secret, password);

            if (username != userInfo.Username || hashPassword != userInfo.Password)
            {
                return(null);
            }

            var eventData = new UserLoginEvent();
            var evt       = this.CreateEvent(eventData);
            await Claptrap.HandleEventAsync(evt);

            var jwt = CreateJwt(UserId, userInfo.Secret);

            return(jwt);
        }
コード例 #22
0
        public Task ChangeBalanceAsync(decimal diff)
        {
            var accountStateData = (AccountStateData)Claptrap.State.Data;

            if (accountStateData.Balance + diff < 0)
            {
                return(Task.CompletedTask);
            }

            var dataEvent = new DataEvent(
                Claptrap.State.Identity,
                ClaptrapCodes.BalanceChangeEvent,
                new ChangeAccountBalanceEventData
            {
                Diff       = diff,
                NewBalance = accountStateData.Balance + diff,
                OldBalance = accountStateData.Balance,
            });

            return(Claptrap.HandleEventAsync(dataEvent));
        }
コード例 #23
0
 public Task ActivateAsync()
 {
     return(Claptrap.ActivateAsync());
 }
コード例 #24
0
        private async Task <bool> ContinueCoreAsync()
        {
            var flowState = StateData.SagaFlowState;

            if (flowState.IsCompensated)
            {
                _logger.LogInformation("saga flow IsCompensated = true, please create a new saga flow.");
                return(false);
            }

            if (flowState.IsCompleted)
            {
                _logger.LogInformation("saga flow IsCompleted = true, please create a new saga flow.");
                return(false);
            }

            if (flowState.IsCompensating)
            {
                for (var i = 0;
                     i < flowState.CompensateStepStatuses.Length && i <= flowState.LastErrorStepIndex;
                     i++)
                {
                    var status = flowState.CompensateStepStatuses[i];
                    if (status != StepStatus.Completed)
                    {
                        await Claptrap.HandleEventAsync(new DataEvent(_identity,
                                                                      SagaCodes.Compensate,
                                                                      new SagaCompensateStepEvent
                        {
                            StepIndex = i,
                        }));

                        return(true);
                    }
                }
            }

            for (var i = 0; i < flowState.StepStatuses.Length; i++)
            {
                var status = flowState.StepStatuses[i];
                switch (status)
                {
                case StepStatus.Completed:
                    continue;

                case StepStatus.NotStarted:
                    await Claptrap.HandleEventAsync(new DataEvent(_identity,
                                                                  SagaCodes.MoveToNext,
                                                                  new SagaMoveToNextEvent
                    {
                        StepIndex = i,
                    }));

                    return(true);

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            _logger.LogInformation("saga flow done");
            return(false);
        }
コード例 #25
0
ファイル: Burning.cs プロジェクト: xcl-net/Newbe.Claptrap
 public Task DeactivateAsync()
 {
     return(Claptrap.DeactivateAsync());
 }