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)); }
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); }
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); }
public void Publish(T message) { _publisher.Publish(message); }