public async Task <TResponse> CallAsync <TRequest, TResponse>(TRequest request, string exchangeName, string subscriberQueueName, string routingKey = "")
        {
            _rabbitMqSubscriber.Subscribe(subscriberQueueName, OnMessageReceived);

            var tcs = new TaskCompletionSource <string>();

            var ct = new CancellationTokenSource(TimeSpan.FromMilliseconds(TIMEOUT_MS));

            ct.Token.Register(() => tcs.TrySetCanceled(), false);

            var correlationId = Guid.NewGuid().ToString();

            _pendingMessages[correlationId] = tcs;

            _logger.LogInformation("RPC request {@Data}", new
            {
                CorrelationId = correlationId
            });

            _rabbitMqPublisher.Publish(request, exchangeName, routingKey, subscriberQueueName, correlationId);

            var response = await tcs.Task;

            _logger.LogInformation("Received RPC response {@Data}", new
            {
                CorrelationId = correlationId
            });

            return(JsonConvert.DeserializeObject <TResponse>(response));
        }
Exemple #2
0
        public async Task Poll(string exchangeName, TimeSpan timeout)
        {
            var       tokenSource     = new CancellationTokenSource(timeout);
            var       watch           = new Stopwatch();
            var       requestDuration = 0;
            Exception exception       = null;
            ExchangeHealthControlReportType type;

            //request positions state
            try
            {
                watch.Start();

                var requestResult =
                    await _exchangeConnectorService.GetOpenedPositionAsync(exchangeName, tokenSource.Token);

                requestDuration = (int)watch.ElapsedMilliseconds;
                type            = requestResult == null
                    ? ExchangeHealthControlReportType.NoPositionData
                    : ExchangeHealthControlReportType.Ok;
            }
            catch (OperationCanceledException ex)
            {
                exception = ex;
                type      = ExchangeHealthControlReportType.ExceptionRased;
            }
            catch (Exception ex)
            {
                exception = ex;
                type      = ExchangeHealthControlReportType.ExceptionRased;

                if (!_warningCache.TryGetValue(exchangeName, out var lastWarning) ||
                    DateTime.UtcNow.Subtract(lastWarning).TotalSeconds > _failMessageThrottlingPeriodSec)
                {
                    _warningCache.AddOrUpdate(exchangeName, DateTime.UtcNow, (e, t) => DateTime.UtcNow);
                    await _log.WriteWarningAsync(nameof(ExchangeHealthControlService), nameof(Poll),
                                                 $"Exception occured while polling {exchangeName}.", ex, DateTime.UtcNow);
                }
            }

            var report = new ExchangeHealthControlResult(
                exchangeName,
                requestDuration,
                type.ToString(),
                exception,
                type == ExchangeHealthControlReportType.Ok);

            //push result to the rabbit (to be consumed by Hedging)
            await _exchangeHealthControlReportPublisher.Publish(ContractMapper.Map <ExchangeHealthControlReport>(report));

            //write statistic to table
            await _exchangeHealthControlResultRepository.InsertOrUpdateAsync(report);
        }
Exemple #3
0
        public async Task Poll(string exchangeName, TimeSpan timeout)
        {
            var             tokenSource = new CancellationTokenSource(timeout);
            List <Position> positions   = null;

            //retrieve positions
            try
            {
                positions = (await _exchangeConnectorService.GetOpenedPositionAsync(exchangeName, tokenSource.Token))
                            .Select(Position.Create).ToList();
            }
            catch (Exception ex)
            {
                await _log.WriteErrorAsync(nameof(ExchangePollingService), nameof(Poll), ex, DateTime.UtcNow);

                //TODO consider slack notification here
                return;
            }

            var exchange = _exchangeCache.GetOrCreate(exchangeName);

            //perform checking
            var checkResults = CheckPositions(exchange, positions);

            //create diff order for Risk System
            var executedTrades = checkResults
                                 .Select(x => CreateExecutionReport(exchangeName, x.Item1, x.Item2))
                                 //do nothing if there's no quotes on any instrument, and wait for actual quotes.
                                 .Where(x => x != null)
                                 .ToList();

            if (executedTrades.Count == 0)
            {
                return;
            }

            //publish trades for Risk System
            foreach (var executedTrade in executedTrades)
            {
                await _executionReportPublisher.Publish(executedTrade);
            }
            await _log.WriteInfoAsync(nameof(ExchangePollingService), nameof(Poll),
                                      $"Execution report have been published for {exchangeName}: {string.Join(", ", executedTrades.Select(x => x.Instrument.Name))}",
                                      DateTime.UtcNow);

            //update positions and push published changes to cache
            exchange.UpdatePositions(positions.Where(x =>
                                                     executedTrades.Select(tr => tr.Instrument.Name).Any(instrument => instrument == x.Symbol)));
            _exchangeCache.Set(exchange);
        }
        private async Task <bool> OnMessageReceived <TRequest, TResponse>(BasicDeliverEventArgs args, Func <TRequest, Task <TResponse> > action)
        {
            _logger.LogInformation("Received RPC request {@Data}", new
            {
                CorrelationId = args.BasicProperties.CorrelationId
            });

            var messageString = Encoding.UTF8.GetString(args.Body.ToArray());

            var request = JsonConvert.DeserializeObject <TRequest>(messageString);

            var response = await action(request);

            _rabbitMqPublisher.Publish(response, "", args.BasicProperties.ReplyTo,
                                       correlationId: args.BasicProperties.CorrelationId);

            _logger.LogInformation("Published RPC response {@Data}", new
            {
                CorrelationId = args.BasicProperties.CorrelationId
            });

            return(true);
        }
Exemple #5
0
 public void Publish(T message)
 {
     _publisher.Publish(message);
 }