Exemple #1
0
        // ReSharper disable once UnusedMethodReturnValue.Local
        private ValidationResult ValidateMessageProducer(FeedMessage message)
        {
            if (!_producerManager.Exists(message.ProducerId))
            {
                LogFailure(message, "producer", message.ProducerId);
                return(ValidationResult.PROBLEMS_DETECTED);
            }
            var producer = _producerManager.Get(message.ProducerId);

            if (!producer.IsAvailable || producer.IsDisabled)
            {
                LogFailure(message, "producer", message.ProducerId);
                return(ValidationResult.PROBLEMS_DETECTED);
            }
            return(ValidationResult.SUCCESS);
        }
        /// <summary>
        /// Handles the message received event
        /// </summary>
        /// <param name="sender">The <see cref="object"/> representation of the event sender</param>
        /// <param name="eventArgs">A <see cref="BasicDeliverEventArgs"/> containing event information</param>
        private void consumer_OnReceived(object sender, BasicDeliverEventArgs eventArgs)
        {
            if (eventArgs.Body == null || !eventArgs.Body.Any())
            {
                var body = eventArgs.Body == null ? "null" : "empty";
                ExecutionLog.LogWarning($"A message with {body} body received. Aborting message processing");
                return;
            }

            var receivedAt = SdkInfo.ToEpochTime(DateTime.Now);

            // NOT used for GetRawMessage()
            var         sessionName = _interest == null ? "system" : _interest.Name;
            string      messageBody = null;
            FeedMessage feedMessage;
            IProducer   producer;
            string      messageName;

            try
            {
                using (var t = SdkMetricsFactory.MetricsRoot.Measure.Timer.Time(new TimerOptions {
                    Context = "FEED", Name = "Message deserialization time", MeasurementUnit = Unit.Items
                }))
                {
                    t.TrackUserValue(eventArgs.RoutingKey);
                    messageBody = Encoding.UTF8.GetString(eventArgs.Body);
                    feedMessage = _deserializer.Deserialize(new MemoryStream(eventArgs.Body));
                    producer    = _producerManager.Get(feedMessage.ProducerId);
                    messageName = feedMessage.GetType().Name;

                    if (t.Elapsed.TotalMilliseconds > 300)
                    {
                        _keyParser.TryGetSportId(eventArgs.RoutingKey, messageName, out var sportId);
                        var marketCounts  = 0;
                        var outcomeCounts = 0;
                        if (feedMessage is odds_change oddsChange)
                        {
                            marketCounts  = oddsChange.odds?.market?.Length ?? 0;
                            outcomeCounts = oddsChange.odds?.market?.Where(w => w.outcome != null).SelectMany(list => list.outcome).Count() ?? 0;
                        }
                        if (feedMessage is bet_settlement betSettlement)
                        {
                            marketCounts  = betSettlement.outcomes?.Length ?? 0;
                            outcomeCounts = betSettlement.outcomes?.Where(w => w.Items != null).SelectMany(list => list.Items).Count() ?? 0;
                        }
                        ExecutionLog.LogDebug($"Deserialization of {feedMessage.GetType().Name} for {feedMessage.EventId} ({feedMessage.GeneratedAt}) and sport {sportId} took {t.Elapsed.TotalMilliseconds}ms. Markets={marketCounts}, Outcomes={outcomeCounts}");
                    }
                }

                if (producer.IsAvailable && !producer.IsDisabled)
                {
                    FeedLog.LogInformation($"<~> {sessionName} <~> {eventArgs.RoutingKey} <~> {messageBody}");
                }
                else
                {
                    if (FeedLog.IsEnabled(LogLevel.Debug))
                    {
                        FeedLog.LogDebug($"<~> {sessionName} <~> {eventArgs.RoutingKey} <~> {producer.Id}");
                    }
                }

                if (eventArgs.BasicProperties?.Headers != null)
                {
                    feedMessage.SentAt = eventArgs.BasicProperties.Headers.ContainsKey("timestamp_in_ms")
                                             ? long.Parse(eventArgs.BasicProperties.Headers["timestamp_in_ms"].ToString())
                                             : feedMessage.GeneratedAt;
                }
                feedMessage.ReceivedAt = receivedAt;
                SdkMetricsFactory.MetricsRoot.Measure.Meter.Mark(new MeterOptions {
                    Context = "FEED", Name = "Message received"
                }, MetricTags.Empty, messageName);
            }
            catch (DeserializationException ex)
            {
                ExecutionLog.LogError($"Failed to parse message. RoutingKey={eventArgs.RoutingKey} Message: {messageBody}", ex);
                SdkMetricsFactory.MetricsRoot.Measure.Meter.Mark(new MeterOptions {
                    Context = "FEED", Name = "Message deserialization exception"
                }, MetricTags.Empty, eventArgs.RoutingKey);
                RaiseDeserializationFailed(eventArgs.Body);
                return;
            }
            catch (Exception ex)
            {
                ExecutionLog.LogError($"Error consuming feed message. RoutingKey={eventArgs.RoutingKey} Message: {messageBody}", ex);
                SdkMetricsFactory.MetricsRoot.Measure.Meter.Mark(new MeterOptions {
                    Context = "FEED", Name = "Exception consuming feed message"
                }, MetricTags.Empty, eventArgs.RoutingKey);
                RaiseDeserializationFailed(eventArgs.Body);
                return;
            }

            // send RawFeedMessage if needed
            try
            {
                if (producer.IsAvailable && !producer.IsDisabled)
                {
                    //ExecutionLog.LogDebug($"Raw msg [{_interest}]: {feedMessage.GetType().Name} for event {feedMessage.EventId}.");
                    var args = new RawFeedMessageEventArgs(eventArgs.RoutingKey, feedMessage, sessionName);
                    RawFeedMessageReceived?.Invoke(this, args);
                }
            }
            catch (Exception e)
            {
                ExecutionLog.LogError($"Error dispatching raw message for {feedMessage.EventId}", e);
            }
            // continue normal processing

            if (!_producerManager.Exists(feedMessage.ProducerId))
            {
                ExecutionLog.LogWarning($"A message for producer which is not defined was received. Producer={feedMessage.ProducerId}");
                return;
            }

            if (!_useReplay && (!producer.IsAvailable || producer.IsDisabled))
            {
                ExecutionLog.LogDebug($"A message for producer which is disabled was received. Producer={producer}, MessageType={messageName}");
                return;
            }

            ExecutionLog.LogInformation($"Message received. Message=[{feedMessage}].");
            if (feedMessage.IsEventRelated)
            {
                if (!string.IsNullOrEmpty(eventArgs.RoutingKey) && _keyParser.TryGetSportId(eventArgs.RoutingKey, messageName, out var sportId))
                {
                    feedMessage.SportId = sportId;
                }
                else
                {
                    ExecutionLog.LogWarning($"Failed to parse the SportId from the routing key. RoutingKey={eventArgs.RoutingKey}, message=[{feedMessage}]. SportId will not be set.");
                }
            }

            RaiseMessageReceived(feedMessage, eventArgs.Body);
        }
Exemple #3
0
        /// <summary>
        /// Handles the message received event
        /// </summary>
        /// <param name="sender">The <see cref="object"/> representation of the event sender</param>
        /// <param name="eventArgs">A <see cref="BasicDeliverEventArgs"/> containing event information</param>
        private void consumer_OnReceived(object sender, BasicDeliverEventArgs eventArgs)
        {
            if (eventArgs.Body == null || !eventArgs.Body.Any())
            {
                ExecutionLog.WarnFormat("A message with {0} body received. Aborting message processing", eventArgs.Body == null ? "null" : "empty");
                return;
            }

            var receivedAt = SdkInfo.ToEpochTime(DateTime.Now);

            // NOT used for GetRawMessage()
            var         sessionName = _interest == null ? "system" : _interest.Name;
            string      messageBody = null;
            FeedMessage feedMessage;

            try
            {
                if (FeedLog.IsDebugEnabled)
                {
                    messageBody = Encoding.UTF8.GetString(eventArgs.Body);
                    FeedLog.Debug($"<~> {sessionName} <~> {eventArgs.RoutingKey} <~> {messageBody}");
                }
                else
                {
                    FeedLog.Info(eventArgs.RoutingKey);
                }
                feedMessage = _deserializer.Deserialize(new MemoryStream(eventArgs.Body));
                if (eventArgs.BasicProperties?.Headers != null)
                {
                    feedMessage.SentAt = eventArgs.BasicProperties.Headers.ContainsKey("timestamp_in_ms")
                                             ? long.Parse(eventArgs.BasicProperties.Headers["timestamp_in_ms"].ToString())
                                             : feedMessage.GeneratedAt;
                }
                feedMessage.ReceivedAt = receivedAt;
            }
            catch (DeserializationException ex)
            {
                ExecutionLog.Error($"Failed to parse message. RoutingKey={eventArgs.RoutingKey} Message: {messageBody}", ex);
                Metric.Context("RABBIT").Meter("RabbitMqMessageReceiver->DeserializationException", Unit.Calls).Mark();
                RaiseDeserializationFailed(eventArgs.Body);
                return;
            }

            // send RawFeedMessage if needed
            try
            {
                //ExecutionLog.Debug($"Raw msg [{_interest}]: {feedMessage.GetType().Name} for event {feedMessage.EventId}.");
                var args = new RawFeedMessageEventArgs(eventArgs.RoutingKey, feedMessage, sessionName);
                RawFeedMessageReceived?.Invoke(this, args);
            }
            catch (Exception e)
            {
                ExecutionLog.Error($"Error dispatching raw message for {feedMessage.EventId}", e);
            }
            // continue normal processing

            if (!_producerManager.Exists(feedMessage.ProducerId))
            {
                ExecutionLog.Warn($"A message for producer which is not defined was received. Producer={feedMessage.ProducerId}");
                return;
            }

            var producer    = _producerManager.Get(feedMessage.ProducerId);
            var messageName = feedMessage.GetType().Name;

            if (!_useReplay && (!producer.IsAvailable || producer.IsDisabled))
            {
                ExecutionLog.Debug($"A message for producer which is disabled was received. Producer={producer}, MessageType={messageName}");
                return;
            }

            ExecutionLog.Info($"Message received. Message=[{feedMessage}].");
            if (feedMessage.IsEventRelated)
            {
                URN sportId;
                if (!string.IsNullOrEmpty(eventArgs.RoutingKey) && _keyParser.TryGetSportId(eventArgs.RoutingKey, messageName, out sportId))
                {
                    feedMessage.SportId = sportId;
                }
                else
                {
                    ExecutionLog.Warn($"Failed to parse the SportId from the routing key. RoutingKey={eventArgs.RoutingKey}, message=[{feedMessage}]. SportId will not be set.");
                }
            }

            Metric.Context("RABBIT").Meter("RabbitMqMessageReceiver", Unit.Items).Mark(messageName);
            RaiseMessageReceived(feedMessage, eventArgs.Body);
        }