コード例 #1
0
        public async Task Handle(StartLiquidationInternalCommand command,
                                 IEventPublisher publisher)
        {
            #region Private Methods

            void PublishFailedEvent(string reason)
            {
                publisher.PublishEvent(new LiquidationFailedEvent
                {
                    OperationId     = command.OperationId,
                    CreationTime    = _dateService.Now(),
                    Reason          = reason,
                    LiquidationType = command.LiquidationType.ToType <LiquidationTypeContract>(),
                    AccountId       = command.AccountId,
                    AssetPairId     = command.AssetPairId,
                    Direction       = command.Direction?.ToType <PositionDirectionContract>(),
                });

                _liquidationEndEventChannel.SendEvent(this, new LiquidationEndEventArgs
                {
                    OperationId           = command.OperationId,
                    CreationTime          = _dateService.Now(),
                    AccountId             = command.AccountId,
                    LiquidatedPositionIds = new List <string>(),
                    FailReason            = reason,
                });
            }

            #endregion

            #region Validations

            if (string.IsNullOrEmpty(command.AccountId))
            {
                PublishFailedEvent("AccountId must be specified");
                return;
            }

            if (_accountsCache.TryGet(command.AccountId) == null)
            {
                PublishFailedEvent("Account does not exist");
                return;
            }

            #endregion

            var(executionInfo, _) = await _operationExecutionInfoRepository.GetOrAddAsync(
                operationName : LiquidationSaga.OperationName,
                operationId : command.OperationId,
                factory : () => new OperationExecutionInfo <LiquidationOperationData>(
                    operationName: LiquidationSaga.OperationName,
                    id: command.OperationId,
                    lastModified: _dateService.Now(),
                    data: new LiquidationOperationData
            {
                State                 = LiquidationOperationState.Initiated,
                AccountId             = command.AccountId,
                AssetPairId           = command.AssetPairId,
                QuoteInfo             = command.QuoteInfo,
                Direction             = command.Direction,
                LiquidatedPositionIds = new List <string>(),
                ProcessedPositionIds  = new List <string>(),
                LiquidationType       = command.LiquidationType,
                OriginatorType        = command.OriginatorType,
                AdditionalInfo        = command.AdditionalInfo,
                StartedAt             = command.CreationTime
            }
                    ));

            if (executionInfo.Data.State == LiquidationOperationState.Initiated)
            {
                if (!_accountsCache.TryStartLiquidation(command.AccountId, command.OperationId,
                                                        out var currentOperationId))
                {
                    if (currentOperationId != command.OperationId)
                    {
                        PublishFailedEvent(
                            $"Liquidation is already in progress. Initiated by operation : {currentOperationId}");
                        return;
                    }
                }

                _chaosKitty.Meow(
                    $"{nameof(StartLiquidationInternalCommand)}:" +
                    $"Publish_LiquidationStartedInternalEvent:" +
                    $"{command.OperationId}");

                publisher.PublishEvent(new LiquidationStartedEvent
                {
                    OperationId     = command.OperationId,
                    CreationTime    = _dateService.Now(),
                    AssetPairId     = executionInfo.Data.AssetPairId,
                    AccountId       = executionInfo.Data.AccountId,
                    LiquidationType = executionInfo.Data.LiquidationType.ToType <LiquidationTypeContract>()
                });
            }
        }