private async Task Handle(TransactionProcessedEvent evt, ICommandSender sender) { ChaosKitty.Meow(); var clientAcc = await _clientAccountClient.GetByIdAsync(evt.ClientId); var sendEmailCommand = new SendNoRefundDepositDoneMailCommand { Email = clientAcc.Email, Amount = evt.Amount, AssetId = evt.Asset.Id }; sender.SendCommand(sendEmailCommand, "email"); ChaosKitty.Meow(); var pushSettings = await _clientAccountClient.GetPushNotificationAsync(evt.ClientId); if (pushSettings.Enabled) { var sendNotificationCommand = new SendNotificationCommand { NotificationId = clientAcc.NotificationsId, Type = NotificationType.TransactionConfirmed, Message = string.Format(TextResources.CashInSuccessText, new decimal(evt.Amount).TruncateDecimalPlaces(evt.Asset.Accuracy), evt.Asset.Id) }; sender.SendCommand(sendNotificationCommand, "notifications"); } }
private void RequestPrice(ICommandSender sender, IOperationExecutionInfo <SpecialLiquidationOperationData> executionInfo) { //hack, requested by the bank var positionsVolume = executionInfo.Data.Volume != 0 ? executionInfo.Data.Volume : 1; var command = new GetPriceForSpecialLiquidationCommand { OperationId = executionInfo.Id, CreationTime = _dateService.Now(), Instrument = executionInfo.Data.Instrument, Volume = positionsVolume, RequestNumber = executionInfo.Data.RequestNumber, RequestedFromCorporateActions = executionInfo.Data.RequestedFromCorporateActions }; if (_marginTradingSettings.ExchangeConnector == ExchangeConnectorType.RealExchangeConnector) { //send it to the Gavel sender.SendCommand(command, _cqrsContextNamesSettings.Gavel); } else { _specialLiquidationService.SavePriceRequestForSpecialLiquidation(command); } //special command is sent instantly for timeout control.. it is retried until timeout occurs sender.SendCommand(new GetPriceForSpecialLiquidationTimeoutInternalCommand { OperationId = executionInfo.Id, CreationTime = _dateService.Now(), TimeoutSeconds = _marginTradingSettings.SpecialLiquidation.PriceRequestTimeoutSec, RequestNumber = executionInfo.Data.RequestNumber }, _cqrsContextNamesSettings.TradingEngine); }
private void LiquidatePositionsIfAnyAvailable(string operationId, LiquidationOperationData data, ICommandSender sender) { var liquidationData = GetLiquidationData(data); if (!liquidationData.HasValue || !liquidationData.Value.Positions.Any()) { sender.SendCommand(new FailLiquidationInternalCommand { OperationId = operationId, CreationTime = _dateService.Now(), Reason = "Nothing to liquidate", LiquidationType = data.LiquidationType, }, _cqrsContextNamesSettings.TradingEngine); } else { sender.SendCommand(new LiquidatePositionsInternalCommand { OperationId = operationId, CreationTime = _dateService.Now(), PositionIds = liquidationData.Value.Positions, AssetPairId = liquidationData.Value.AssetPairId, }, _cqrsContextNamesSettings.TradingEngine); } }
public async Task <ActionResult <bool> > CreateOrderFromBasketDataAsync([FromBody] UserCheckoutAcceptedModel request) { var createOrderCommand = new CreateOrderCommand(request.Basket.Items, request.UserId, request.UserName, request.City, request.Street, request.State, request.Country, request.ZipCode, request.CardNumber, request.CardHolderName, request.CardExpiration, request.CardSecurityNumber, request.CardTypeId); return(await _commandSender.SendCommand(createOrderCommand)); }
private async Task Handle(EnrolledBalanceSetEvent evt, ICommandSender sender) { var aggregate = await _cashinRepository.GetAsync(evt.OperationId); var transitionResult = aggregate.OnEnrolledBalanceSet(); if (transitionResult.ShouldSaveAggregate()) { await _cashinRepository.SaveAsync(aggregate); } if (transitionResult.ShouldSendCommands()) { if (!aggregate.IsDustCashin.HasValue) { throw new InvalidOperationException("IsDustCashin should be not null here"); } if (!aggregate.IsDustCashin.Value) { if (!aggregate.BalanceAmount.HasValue) { throw new InvalidOperationException("Balance amount should be not null here"); } sender.SendCommand ( new StartOperationExecutionCommand { Amount = aggregate.BalanceAmount.Value, AssetId = aggregate.AssetId, FromAddress = aggregate.DepositWalletAddress, IncludeFee = true, OperationId = aggregate.OperationId, ToAddress = aggregate.HotWalletAddress }, BlockchainOperationsExecutorBoundedContext.Name ); } else { sender.SendCommand ( new ReleaseDepositWalletLockCommand { OperationId = aggregate.OperationId, BlockchainType = aggregate.BlockchainType, BlockchainAssetId = aggregate.BlockchainAssetId, DepositWalletAddress = aggregate.DepositWalletAddress }, Self ); } _chaosKitty.Meow(aggregate.OperationId); } }
private void ContinueOrFinishLiquidation(string operationId, LiquidationOperationData data, ICommandSender sender) { void FinishWithReason(string reason) => sender.SendCommand(new FinishLiquidationInternalCommand { OperationId = operationId, CreationTime = _dateService.Now(), Reason = reason, LiquidationType = data.LiquidationType, ProcessedPositionIds = data.ProcessedPositionIds, LiquidatedPositionIds = data.LiquidatedPositionIds, }, _cqrsContextNamesSettings.TradingEngine); var account = _accountsCacheService.TryGet(data.AccountId); if (account == null) { sender.SendCommand(new FailLiquidationInternalCommand { OperationId = operationId, CreationTime = _dateService.Now(), Reason = "Account does not exist", LiquidationType = data.LiquidationType, }, _cqrsContextNamesSettings.TradingEngine); return; } var accountLevel = account.GetAccountLevel(); if (data.LiquidationType == LiquidationType.Forced) { if (!_ordersCache.Positions.GetPositionsByAccountIds(data.AccountId) .Any(x => (string.IsNullOrWhiteSpace(data.AssetPairId) || x.AssetPairId == data.AssetPairId) && x.OpenDate < data.StartedAt && (data.Direction == null || x.Direction == data.Direction))) { FinishWithReason("All positions are closed"); } else { LiquidatePositionsIfAnyAvailable(operationId, data, sender); } return; } if (accountLevel < AccountLevel.StopOut) { FinishWithReason($"Account margin level is {accountLevel}"); } else { LiquidatePositionsIfAnyAvailable(operationId, data, sender); } }
private async Task Handle(PriceForSpecialLiquidationCalculatedEvent e, ICommandSender sender) { var executionInfo = await _operationExecutionInfoRepository.GetAsync <SpecialLiquidationOperationData>( operationName : OperationName, id : e.OperationId); if (executionInfo?.Data == null) { return; } if (executionInfo.Data.SwitchState(SpecialLiquidationOperationState.PriceRequested, SpecialLiquidationOperationState.PriceReceived)) { //validate that volume didn't changed to peek either to execute order or request the price again var currentVolume = GetNetPositionCloseVolume(executionInfo.Data.PositionIds, executionInfo.Data.AccountId); if (currentVolume != 0 && currentVolume != e.Volume) { sender.SendCommand(new GetPriceForSpecialLiquidationCommand { OperationId = e.OperationId, CreationTime = _dateService.Now(), Instrument = executionInfo.Data.Instrument, Volume = currentVolume, RequestNumber = e.RequestNumber++, AccountId = executionInfo.Data.AccountId, }, _cqrsContextNamesSettings.Gavel); executionInfo.Data.Volume = currentVolume; await _operationExecutionInfoRepository.Save(executionInfo); return;//wait for the new price } executionInfo.Data.Price = e.Price; //execute order in Gavel by API sender.SendCommand(new ExecuteSpecialLiquidationOrderCommand { OperationId = e.OperationId, CreationTime = _dateService.Now(), Instrument = executionInfo.Data.Instrument, Volume = executionInfo.Data.Volume, Price = e.Price, }, _cqrsContextNamesSettings.TradingEngine); _chaosKitty.Meow(e.OperationId); await _operationExecutionInfoRepository.Save(executionInfo); } }
private async Task Handle(SpecialLiquidationStartedInternalEvent e, ICommandSender sender) { var executionInfo = await _operationExecutionInfoRepository.GetAsync <SpecialLiquidationOperationData>( operationName : OperationName, id : e.OperationId); if (executionInfo?.Data == null) { return; } if (executionInfo.Data.SwitchState(SpecialLiquidationOperationState.Started, SpecialLiquidationOperationState.PriceRequested)) { var positionsVolume = GetNetPositionCloseVolume(executionInfo.Data.PositionIds, executionInfo.Data.AccountId); //special command is sent instantly for timeout control.. it is retried until timeout occurs sender.SendCommand(new GetPriceForSpecialLiquidationTimeoutInternalCommand { OperationId = e.OperationId, CreationTime = _dateService.Now(), TimeoutSeconds = _marginTradingSettings.SpecialLiquidation.PriceRequestTimeoutSec, }, _cqrsContextNamesSettings.TradingEngine); executionInfo.Data.Instrument = e.Instrument; executionInfo.Data.Volume = positionsVolume; if (_marginTradingSettings.ExchangeConnector == ExchangeConnectorType.RealExchangeConnector) { //send it to the Gavel sender.SendCommand(new GetPriceForSpecialLiquidationCommand { OperationId = e.OperationId, CreationTime = _dateService.Now(), Instrument = e.Instrument, Volume = positionsVolume != 0 ? positionsVolume : 1,//hack, requested by the bank RequestNumber = 1, }, _cqrsContextNamesSettings.Gavel); } else { _specialLiquidationService.FakeGetPriceForSpecialLiquidation(e.OperationId, e.Instrument, positionsVolume); } _chaosKitty.Meow(e.OperationId); await _operationExecutionInfoRepository.Save(executionInfo); } }
private void ProcessQueueItem(FeedQueueItem queueItem, IVkDataProvider vkDataProvider, FeedProcessingConfig processingConfig) { try { if (!this.feedProviders.ContainsKey(queueItem.QueueItemType)) { throw new ArgumentException(string.Format("Unsupported feed type provided: \"{0}\"", queueItem.QueueItemType)); } var feedProvider = this.feedProviders[queueItem.QueueItemType]; var vkGroup = this.groupRepository.GetGroupById(queueItem.VkGroupId); if (vkGroup == null) { this.log.InfoFormat("Group with Id = \"{0}\" not found. Processing stopped.", queueItem.VkGroupId); return; } this.log.InfoFormat("Fetching of feed '{0}' for VkGroupId {1} is started", queueItem.QueueItemType, queueItem.VkGroupId); using (ICommandSender commandSender = Factory.GetInstance <ICommandSender>().Open(processingConfig.OutputQueueId)) { foreach (var dataFeed in feedProvider.GetFeeds(vkDataProvider, vkGroup)) { dataFeed.TtlInMinutes = processingConfig.TtlInMinutes; commandSender.SendCommand(dataFeed); } var terminator = new DataFeed { IsSequenceTerminator = true, ReceivedAt = this.dateTimeHelper.GetDateTimeNow(), SendingDate = this.dateTimeHelper.GetDateTimeNow(), VkGroupId = vkGroup.Id, Type = feedProvider.ProvidedDataType, FetchingServer = this.webUtilities.GetServerName(), FetchingProcess = this.webUtilities.GetApplicationPoolName() }; commandSender.SendCommand(terminator); } this.log.InfoFormat("Fetching of feed '{0}' for VkGroupId {1} is finished", queueItem.QueueItemType, queueItem.VkGroupId); } catch (Exception exc) { this.log.Error(string.Format("Fetching of feed '{0}' for VkGroupId {1} is FAILED. Reason: {2}", queueItem.QueueItemType, queueItem.VkGroupId, exc)); } }
private async Task Handle(SourceAddressLockReleasedEvent evt, ICommandSender sender) { var aggregate = await _repository.GetAsync(evt.TransactionId); if (_stateSwitcher.Switch(aggregate, evt)) { switch (aggregate.State) { case TransactionExecutionState.WaitingForEnding: sender.SendCommand ( new WaitForTransactionEndingCommand { OperationId = aggregate.OperationId, TransactionId = aggregate.TransactionId, TransactionNumber = aggregate.TransactionNumber, BlockchainType = aggregate.BlockchainType, BlockchainAssetId = aggregate.BlockchainAssetId, Outputs = aggregate.Outputs .Select(o => o.ToContract()) .ToArray() }, Self ); break; case TransactionExecutionState.SourceAddressReleased: sender.SendCommand ( new ClearBroadcastedTransactionCommand { OperationId = aggregate.OperationId, TransactionId = aggregate.TransactionId, BlockchainType = aggregate.BlockchainType }, Self ); break; default: throw new InvalidOperationException($"Unexpected aggregate state [{aggregate.State}]"); } _chaosKitty.Meow(evt.TransactionId); await _repository.SaveAsync(aggregate); } }
public async Task Handle(NotEnoughLiquidityInternalEvent e, ICommandSender sender) { var executionInfo = await _operationExecutionInfoRepository.GetAsync <LiquidationOperationData>( operationName : OperationName, id : e.OperationId); if (executionInfo?.Data == null) { return; } if (executionInfo.Data.SwitchState(LiquidationOperationState.Started, LiquidationOperationState.SpecialLiquidationStarted)) { sender.SendCommand(new StartSpecialLiquidationInternalCommand { OperationId = Guid.NewGuid().ToString(), CreationTime = _dateService.Now(), AccountId = executionInfo.Data.AccountId, PositionIds = e.PositionIds, CausationOperationId = e.OperationId, AdditionalInfo = executionInfo.Data.AdditionalInfo, OriginatorType = executionInfo.Data.OriginatorType }, _cqrsContextNamesSettings.TradingEngine); _chaosKitty.Meow( $"{nameof(PositionsLiquidationFinishedInternalEvent)}:" + $"Save_OperationExecutionInfo:" + $"{e.OperationId}"); await _operationExecutionInfoRepository.Save(executionInfo); } }
private async Task Handle(SourceAddressLockedEvent evt, ICommandSender sender) { var aggregate = await _repository.GetAsync(evt.TransactionId); if (_stateSwitcher.Switch(aggregate, evt)) { sender.SendCommand ( new BuildTransactionCommand { OperationId = aggregate.OperationId, TransactionId = aggregate.TransactionId, TransactionNumber = aggregate.TransactionNumber, BlockchainType = aggregate.BlockchainType, BlockchainAssetId = aggregate.BlockchainAssetId, FromAddress = aggregate.FromAddress, Outputs = aggregate.Outputs .Select(e => e.ToContract()) .ToArray(), IncludeFee = aggregate.IncludeFee }, Self ); _chaosKitty.Meow(evt.TransactionId); await _repository.SaveAsync(aggregate); } }
private async Task Handle(TransactionExecutionStartedEvent evt, ICommandSender sender) { var aggregate = await _repository.GetOrAddAsync( evt.TransactionId, () => TransactionExecutionAggregate.Start( evt.OperationId, evt.TransactionId, evt.TransactionNumber, evt.FromAddress, evt.Outputs .Select(e => e.ToDomain()) .ToArray(), evt.BlockchainType, evt.BlockchainAssetId, evt.AssetId, evt.IncludeFee)); _chaosKitty.Meow(evt.TransactionId); if (aggregate.State == TransactionExecutionState.Started) { sender.SendCommand ( new LockSourceAddressCommand { OperationId = aggregate.OperationId, TransactionId = aggregate.TransactionId, BlockchainType = aggregate.BlockchainType, FromAddress = aggregate.FromAddress }, Self ); } }
public Task SendMissedMessagesAsync(ICommandSender sender, SayPlace place, string target, int accountID, int maxCount = MessageResendCount) { return(Task.Run(async() => { await sendHistorySemaphore.WaitAsync(); try { using (var db = new ZkDataContext()) { var acc = db.Accounts.Find(accountID); foreach (var entry in db.LobbyChatHistories.Where(x => (x.Target == target) && (x.SayPlace == place) && (x.Time >= acc.LastLogout)) .OrderByDescending(x => x.Time) .Take(maxCount) .OrderBy(x => x.Time)) { await sender.SendCommand(entry.ToSay()); } } } catch (Exception ex) { Trace.TraceError("Error sending chat history: {0}", ex); } finally { sendHistorySemaphore.Release(); } })); }
public void DeleteProject(int projectId, int groupId) { using (ICommandSender commandSender = Factory.GetInstance <ICommandSender>().Open(CONST_DeleteProjectQueueName)) { try { string ticketId = Guid.NewGuid().ToString(); DeleteProjectCommand command = new DeleteProjectCommand { ProjectId = projectId, GroupId = groupId, TicketId = ticketId }; commandSender.SendCommand(command); } catch (Exception e) { e.ToString(); } using (this.unitOfWorkProvider.CreateUnitOfWork()) { var accountId = this.currentUserProvider.GetCurrentUser().GetAccount().Id; var project1 = this.projectRepository.GetByAccountId(accountId).FirstOrDefault(x => x.Id == projectId); if (project1 != null) { this.projectRepository.Delete(project1); } } } }
private async Task Handle(SpecialLiquidationCancelledEvent e, ICommandSender sender) { var executionInfo = await _operationExecutionInfoRepository.GetAsync <SpecialLiquidationOperationData>( operationName : OperationName, id : e.OperationId); if (executionInfo?.Data == null) { return; } if (executionInfo.Data.SwitchState(executionInfo.Data.State,//from any state SpecialLiquidationOperationState.Cancelled)) { if (e.ClosePositions) { sender.SendCommand(new ClosePositionsRegularFlowCommand { OperationId = e.OperationId }, _cqrsContextNamesSettings.TradingEngine); } _chaosKitty.Meow(e.OperationId); await _operationExecutionInfoRepository.Save(executionInfo); } }
private async Task Handle(AccountsBlockedForDeletionEvent e, ICommandSender sender) { var executionInfo = await _executionInfoRepository.GetAsync <DeleteAccountsData>( OperationName, e.OperationId ); if (executionInfo == null) { return; } if (executionInfo.Data.SwitchState(DeleteAccountsState.Started, DeleteAccountsState.MtCoreAccountsBlocked)) { executionInfo.Data.AddFailedIfNotExist(e.FailedAccountIds); sender.SendCommand(new MarkAccountsAsDeletedInternalCommand { OperationId = e.OperationId, Timestamp = _systemClock.UtcNow.UtcDateTime, }, _contextNames.AccountsManagement); _chaosKitty.Meow( $"{nameof(AccountsBlockedForDeletionEvent)}: " + "Save_OperationExecutionInfo: " + $"{e.OperationId}"); await _executionInfoRepository.SaveAsync(executionInfo); } }
private async Task Handle(SpecialLiquidationFinishedEvent e, ICommandSender sender) { var executionInfo = await _operationExecutionInfoRepository.GetAsync <SpecialLiquidationOperationData>( operationName : OperationName, id : e.OperationId); if (executionInfo?.Data == null) { return; } if (executionInfo.Data.SwitchState(SpecialLiquidationOperationState.InternalOrdersExecuted, SpecialLiquidationOperationState.Finished)) { if (!string.IsNullOrEmpty(executionInfo.Data.CausationOperationId)) { sender.SendCommand(new ResumeLiquidationInternalCommand { OperationId = executionInfo.Data.CausationOperationId, CreationTime = _dateService.Now(), Comment = $"Resume after special liquidation {executionInfo.Id} finished", IsCausedBySpecialLiquidation = true, CausationOperationId = executionInfo.Id, PositionsLiquidatedBySpecialLiquidation = executionInfo.Data.PositionIds }, _cqrsContextNamesSettings.TradingEngine); } _chaosKitty.Meow(e.OperationId); await _operationExecutionInfoRepository.Save(executionInfo); } }
private async Task Handle(AccountChangedEvent e, ICommandSender sender) { if (e.Source != OperationName) { return; } var executionInfo = await _executionInfoRepository.GetAsync <GiveTemporaryCapitalData>(OperationName, e.BalanceChange.Id); if (executionInfo == null) { return; } if (executionInfo.Data.SwitchState(TemporaryCapitalState.Started, TemporaryCapitalState.ChargedOnAccount)) { sender.SendCommand( new FinishGiveTemporaryCapitalInternalCommand( e.BalanceChange.Id, _systemClock.UtcNow.UtcDateTime, true, null), _contextNames.AccountsManagement); _chaosKitty.Meow($"{nameof(AccountChangedEvent)}: " + "Save_OperationExecutionInfo:" + e.BalanceChange.Id); await _executionInfoRepository.SaveAsync(executionInfo); } }
public void PutVkGroupToQueue(GroupQueueItem groupQueueItem) { using (ICommandSender commandSender = Factory.GetInstance <ICommandSender>().Open("GroupJobQueue")) { commandSender.SendCommand(groupQueueItem); } }
private async Task Handle(SpecialLiquidationOrderExecutedEvent e, ICommandSender sender) { var executionInfo = await _operationExecutionInfoRepository.GetAsync <SpecialLiquidationOperationData>( operationName : OperationName, id : e.OperationId); if (executionInfo?.Data == null) { return; } if (executionInfo.Data.SwitchState(SpecialLiquidationOperationState.ExternalOrderExecuted, SpecialLiquidationOperationState.InternalOrderExecutionStarted)) { sender.SendCommand(new ExecuteSpecialLiquidationOrdersInternalCommand { OperationId = e.OperationId, CreationTime = _dateService.Now(), Instrument = executionInfo.Data.Instrument, Volume = executionInfo.Data.Volume, Price = e.ExecutionPrice, MarketMakerId = e.MarketMakerId, ExternalOrderId = e.OrderId, ExternalExecutionTime = e.ExecutionTime, }, _cqrsContextNamesSettings.TradingEngine); _chaosKitty.Meow(e.OperationId); await _operationExecutionInfoRepository.Save(executionInfo); } }
public async Task Handle(OperationRejectedEvent evt, ICommandSender sender) { var aggregate = await _riskControlRepository.TryGetAsync(evt.OperationId); if (aggregate == null) { return; // not a cashout operation } if (aggregate.OnOperationRejected(evt.Message)) { // just send a regular CashoutFailed notification sender.SendCommand ( new NotifyCashoutFailedCommand { OperationId = aggregate.OperationId, ClientId = aggregate.ClientId, AssetId = aggregate.AssetId, Amount = aggregate.Amount, StartMoment = aggregate.StartMoment.Value, FinishMoment = aggregate.OperationRejectionMoment.Value, Error = aggregate.Error, ErrorCode = CashoutErrorCode.Unknown }, CqrsModule.Self ); _chaosKitty.Meow(evt.OperationId); await _riskControlRepository.SaveAsync(aggregate); _chaosKitty.Meow(evt.OperationId); } }
private async Task Handle(AccountChangedEvent evt, ICommandSender sender) { if (evt.EventType != AccountChangedEventTypeContract.BalanceUpdated) { return; } if (evt.BalanceChange == null) { return; } var account = await _accountsRepository.GetAsync(evt.Account.Id); var amount = await _negativeProtectionService.CheckAsync(evt.OperationId, evt.Account.Id, evt.BalanceChange.Balance, evt.BalanceChange.ChangeAmount); if (account == null || amount == null) { return; } sender.SendCommand(new NotifyNegativeProtectionInternalCommand( Guid.NewGuid().ToString("N"), evt.OperationId, evt.OperationId, _systemClock.UtcNow.UtcDateTime, account.ClientId, account.Id, amount.Value ), _contextNames.AccountsManagement); }
public async Task Handle(OperationAcceptedEvent evt, ICommandSender sender) { var aggregate = await _riskControlRepository.TryGetAsync(evt.OperationId); if (aggregate == null) { return; // not a cashout operation } if (aggregate.OnOperationAccepted()) { sender.SendCommand ( new AcceptCashoutCommand { OperationId = evt.OperationId, ClientId = aggregate.ClientId, AssetId = aggregate.AssetId, BlockchainType = aggregate.BlockchainType, BlockchainAssetId = aggregate.BlockchainAssetId, HotWalletAddress = aggregate.HotWalletAddress, ToAddress = aggregate.ToAddress, Amount = aggregate.Amount }, Self ); _chaosKitty.Meow(evt.OperationId); await _riskControlRepository.SaveAsync(aggregate); _chaosKitty.Meow(evt.OperationId); } }
private async Task Handle(AmountForWithdrawalFrozenEvent e, ICommandSender sender) { var executionInfo = await _executionInfoRepository.GetAsync <WithdrawalDepositData>(OperationName, e.OperationId); if (executionInfo == null) { return; } if (SwitchState(executionInfo.Data, WithdrawalState.FreezingAmount, WithdrawalState.UpdatingBalance)) { sender.SendCommand( new UpdateBalanceInternalCommand( e.OperationId, executionInfo.Data.AccountId, -executionInfo.Data.Amount, "Funds withdrawal " + executionInfo.Data.Comment, executionInfo.Data.AuditLog, OperationName, AccountBalanceChangeReasonType.Withdraw, e.OperationId, string.Empty, DateTime.UtcNow), _contextNames.AccountsManagement); _chaosKitty.Meow(e.OperationId); await _executionInfoRepository.SaveAsync(executionInfo); } }
public async Task Handle(EodProcessFinishedEvent e, ICommandSender sender) { var productsResult = await _productsRepository.GetAllAsync(null, null, isStarted : false); if (productsResult.IsSuccess && productsResult.Value != null && productsResult.Value.Any()) { var products = productsResult.Value; var markets = products.Select(x => x.Market).Distinct().ToArray(); var marketInfos = await _marketDayOffService.GetMarketsInfo(markets, null); var productsToStart = productsResult.Value .Where(x => x.StartDate < marketInfos[x.Market].NextTradingDayStart.Date.AddDays(1)) .ToList(); _log.WriteInfo(nameof(StartProductsSaga), nameof(Handle), $"Found {productsToStart.Count} products that need to be started. Ids are: {string.Concat(',', productsToStart.Select(x => x.ProductId))}" ); foreach (var product in productsToStart) { sender.SendCommand(new StartProductCommand() { ProductId = product.ProductId, OperationId = e.OperationId, }, _contextNames.AssetService); } } }
public async Task Handle(RiskyOperationDetectedEvent evt, ICommandSender sender) { switch (evt.RiskLevel) { case OperationRiskLevel.ResolutionRequired: if (!string.IsNullOrEmpty(_chatId)) { await _telegramBot.SendTextMessageAsync(_chatId, $"Operation requires for manual confirmation (operationId = {evt.OperationId})"); } sender.SendCommand ( new WaitForOperationResolutionCommand { OperationId = evt.OperationId }, BlockchainRiskControlBoundedContext.Name ); break; default: throw new ArgumentOutOfRangeException(nameof(evt.RiskLevel), evt.RiskLevel, null); } }
private async Task Handle(WithdrawalStartedInternalEvent e, ICommandSender sender) { var executionInfo = await _executionInfoRepository.GetAsync <WithdrawalDepositData>(OperationName, e.OperationId); if (executionInfo == null) { return; } if (SwitchState(executionInfo.Data, WithdrawalState.Created, WithdrawalState.FreezingAmount)) { sender.SendCommand( new FreezeAmountForWithdrawalCommand( executionInfo.Id, _systemClock.UtcNow.UtcDateTime, executionInfo.Data.AccountId, executionInfo.Data.Amount, executionInfo.Data.Comment), _contextNames.TradingEngine); _chaosKitty.Meow(e.OperationId); await _executionInfoRepository.SaveAsync(executionInfo); } }
private async Task Handle(AccountBalanceChangeFailedEvent e, ICommandSender sender) { if (e.Source != OperationName) { return; } var executionInfo = await _executionInfoRepository.GetAsync <WithdrawalDepositData>(OperationName, e.OperationId); if (executionInfo == null) { return; } if (SwitchState(executionInfo.Data, WithdrawalState.UpdatingBalance, WithdrawalState.UnfreezingAmount)) { executionInfo.Data.FailReason = e.Reason; sender.SendCommand( new UnfreezeMarginOnFailWithdrawalCommand( e.OperationId), _contextNames.TradingEngine); _chaosKitty.Meow(e.OperationId); await _executionInfoRepository.SaveAsync(executionInfo); } }
private async Task Handle(AccountChangedEvent e, ICommandSender sender) { if (e.Source != OperationName) { return; } var executionInfo = await _executionInfoRepository.GetAsync <WithdrawalDepositData>(OperationName, e.BalanceChange.Id); if (executionInfo == null) { return; } if (SwitchState(executionInfo.Data, WithdrawalState.UpdatingBalance, WithdrawalState.Succeeded)) { sender.SendCommand( new CompleteWithdrawalInternalCommand( e.BalanceChange.Id), _contextNames.AccountsManagement); _chaosKitty.Meow(e.BalanceChange.Id); await _executionInfoRepository.SaveAsync(executionInfo); } }
public async Task SendMissedMessages(ICommandSender sender, SayPlace place, string target, int accountID, int maxCount = OfflineMessageResendCount) { using (var db = new ZkDataContext()) { var acc = await db.Accounts.FindAsync(accountID); await db.LobbyChatHistories.Where(x => x.Target == target && x.SayPlace == place && x.Time >= acc.LastLogout) .OrderByDescending(x => x.Time) .Take(maxCount) .OrderBy(x => x.Time) .ForEachAsync(async (chatHistory) => { await sender.SendCommand(chatHistory.ToSay()); }); } }
public async Task SendMissedMessages(ICommandSender sender, SayPlace place, string target, int accountID, int maxCount = OfflineMessageResendCount) { using (var db = new ZkDataContext()) { var acc = await db.Accounts.FindAsync(accountID); await db.LobbyChatHistories.Where(x => x.Target == target && x.SayPlace == place && x.Time >= acc.LastLogout) .OrderByDescending(x => x.Time) .Take(maxCount) .OrderBy(x => x.Time) .ForEachAsync(async (chatHistory) => { await sender.SendCommand(chatHistory.ToSay()); }); if (place == SayPlace.User) { // don't keep PMs longer than needed db.LobbyChatHistories.DeleteAllOnSubmit(db.LobbyChatHistories.Where(x => x.Target == target && x.SayPlace == SayPlace.User).ToList()); db.SaveChanges(); } } }
public Task SendMissedMessagesAsync(ICommandSender sender, SayPlace place, string target, int accountID, int maxCount = MessageResendCount) { return Task.Run(async () => { await sendHistorySemaphore.WaitAsync(); try { using (var db = new ZkDataContext()) { var acc = db.Accounts.Find(accountID); foreach (var entry in db.LobbyChatHistories.Where(x => (x.Target == target) && (x.SayPlace == place) && (x.Time >= acc.LastLogout)) .OrderByDescending(x => x.Time) .Take(maxCount) .OrderBy(x => x.Time)) await sender.SendCommand(entry.ToSay()); if (place == SayPlace.User) { // don't keep PMs longer than needed db.LobbyChatHistories.DeleteAllOnSubmit( db.LobbyChatHistories.Where(x => (x.Target == target) && (x.SayPlace == SayPlace.User)).ToList()); db.SaveChanges(); } } } catch (Exception ex) { Trace.TraceError("Error sending chat history: {0}", ex); } finally { sendHistorySemaphore.Release(); } }); }
public async Task OnLoginAccepted(ICommandSender client) { await client.SendCommand(new MatchMakerSetup() { PossibleQueues = possibleQueues }); }