private void ProcessSnapshot(Fixture snapshot, bool isFullSnapshot, bool hasEpochChanged, bool setErrorState = true, bool skipMarketRules = false)
        {
            var logString = isFullSnapshot ? "snapshot" : "stream update";

            if (snapshot == null || (snapshot != null && string.IsNullOrWhiteSpace(snapshot.Id)))
            {
                throw new ArgumentException(string.Format("Received empty {0} for {1}", logString, _resource));
            }

            _logger.InfoFormat("Processing {0} for {1}", logString, snapshot);

            Stopwatch timer = new Stopwatch();

            timer.Start();

            try
            {
                if (isFullSnapshot && !VerifySequenceOnSnapshot(snapshot))
                {
                    return;
                }
                if (IsDisposing || IsStopping)
                {
                    _logger.WarnFormat("Shutting down stream listener, the snapshot {0} won't be processed.", snapshot);
                    return;
                }

                bool is_inplay = string.Equals(snapshot.MatchStatus, ((int)MatchStatus.InRunning).ToString(), StringComparison.OrdinalIgnoreCase);
                IsInPlay = is_inplay;

                if (!skipMarketRules)
                {
                    _marketsRuleManager.ApplyRules(snapshot);

                    snapshot.IsModified = true;
                }
                else
                {
                    _marketsRuleManager.ApplyRules(snapshot, isRemovalDisabled: true);
                }

                if (isFullSnapshot)
                {
                    _platformConnector.ProcessSnapshot(snapshot, hasEpochChanged);
                }
                else
                {
                    _platformConnector.ProcessStreamUpdate(snapshot, hasEpochChanged);
                }

                UpdateState(snapshot, isFullSnapshot);

                IsErrored = false;
            }
            catch (FixtureIgnoredException ex)
            {
                _logger.WarnFormat("{0} received a FixtureIgnoredException", _resource);
                IsIgnored = true;

                _Stats.IncrementValue(AdapterCoreKeys.ERROR_COUNTER);
                RaiseEvent(OnError, ex);
            }
            catch (AggregateException ex)
            {
                _marketsRuleManager.RollbackChanges();

                int total = ex.InnerExceptions.Count;
                int count = 0;
                foreach (var e in ex.InnerExceptions)
                {
                    _logger.Error(string.Format("Error processing {0} for {1} ({2}/{3})", logString, snapshot, ++count, total), e);
                }

                _Stats.IncrementValue(AdapterCoreKeys.ERROR_COUNTER);
                RaiseEvent(OnError, ex);

                if (setErrorState)
                {
                    SetErrorState();
                }
                else
                {
                    throw;
                }
            }
            catch (Exception ex)
            {
                _marketsRuleManager.RollbackChanges();

                _Stats.IncrementValue(AdapterCoreKeys.ERROR_COUNTER);

                _logger.Error(string.Format("Error processing {0} {1}", logString, snapshot), ex);

                RaiseEvent(OnError, ex);

                if (setErrorState)
                {
                    SetErrorState();
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                timer.Stop();
                if (isFullSnapshot)
                {
                    _Stats.AddValue(AdapterCoreKeys.SNAPSHOT_PROCESSING_TIME, timer.ElapsedMilliseconds.ToString());
                }
                else
                {
                    _Stats.AddValue(AdapterCoreKeys.UPDATE_PROCESSING_TIME, timer.ElapsedMilliseconds.ToString());
                }
            }

            _logger.InfoFormat("Finished processing {0} for {1}", logString, snapshot);
        }
        private void ProcessSnapshot(Fixture snapshot, bool isFullSnapshot, bool hasEpochChanged, bool skipMarketRules = false)
        {
            var logString = isFullSnapshot ? "snapshot" : "stream update";

            if (snapshot == null || (snapshot != null && string.IsNullOrWhiteSpace(snapshot.Id)))
            {
                throw new ArgumentException($"Received empty {logString} for {_resource}");
            }

            _logger.Info($"Processing {logString} for {snapshot}");

            try
            {
                if (isFullSnapshot && !VerifySequenceOnSnapshot(snapshot))
                {
                    return;
                }

                _streamStatsActor.Tell(new UpdateStatsStartMsg
                {
                    Fixture          = snapshot,
                    Sequence         = snapshot.Sequence,
                    IsSnapshot       = isFullSnapshot,
                    UpdateReceivedAt = DateTime.UtcNow
                });

                _logger.Info($"BeforeMarketRules MarketsCount={snapshot.Markets.Count} ActiveMarketsCount={snapshot.Markets.Count(_ => _.IsActive)} SelectionsCount={snapshot.Markets.SelectMany(_ => _.Selections).Count()}  {snapshot}");
                if (!skipMarketRules)
                {
                    _marketsRuleManager.ApplyRules(snapshot);
                    snapshot.IsModified = true;
                }
                else
                {
                    _marketsRuleManager.ApplyRules(snapshot, true);
                }
                _logger.Info($"AfterMarketRules MarketsCount={snapshot.Markets.Count} ActiveMarketsCount={snapshot.Markets.Count(_ => _.IsActive)} SelectionsCount={snapshot.Markets.SelectMany(_ => _.Selections).Count()}  {snapshot}");

                if (isFullSnapshot)
                {
                    try
                    {
                        _streamStatsActor.Tell(new UpdatePluginStatsStartMsg()
                        {
                            Fixture          = snapshot,
                            Sequence         = snapshot.Sequence,
                            IsSnapshot       = true,
                            UpdateReceivedAt = DateTime.UtcNow,
                            PluginMethod     = "ProcessSnapshot"
                        });
                        _platformConnector.ProcessSnapshot(snapshot, hasEpochChanged);
                        _streamStatsActor.Tell(new UpdatePluginStatsFinishMsg
                        {
                            CompletedAt = DateTime.UtcNow
                        });
                    }
                    catch (Exception ex)
                    {
                        var pluginError = new PluginException($"Plugin ProcessSnapshot {snapshot} error occured", ex);
                        UpdateStatsError(pluginError);
                        throw pluginError;
                    }
                }
                else
                {
                    try
                    {
                        _streamStatsActor.Tell(new UpdatePluginStatsStartMsg()
                        {
                            Fixture          = snapshot,
                            Sequence         = snapshot.Sequence,
                            IsSnapshot       = false,
                            UpdateReceivedAt = DateTime.UtcNow,
                            PluginMethod     = "ProcessStreamUpdate"
                        });
                        _platformConnector.ProcessStreamUpdate(snapshot, hasEpochChanged);
                        _streamStatsActor.Tell(new UpdatePluginStatsFinishMsg
                        {
                            CompletedAt = DateTime.UtcNow
                        });
                    }
                    catch (Exception ex)
                    {
                        var pluginError = new PluginException($"Plugin ProcessStreamUpdate {snapshot} error occured", ex);
                        UpdateStatsError(pluginError);
                        throw pluginError;
                    }
                }


                UpdateFixtureState(snapshot, isFullSnapshot);
                UpdateSupervisorState(snapshot, isFullSnapshot);

                _streamStatsActor.Tell(new UpdateStatsFinishMsg
                {
                    CompletedAt = DateTime.UtcNow
                });
            }
            catch (FixtureIgnoredException)
            {
                _logger.Warn($"{_resource} received a FixtureIgnoredException");
            }
            catch (AggregateException ex)
            {
                _marketsRuleManager.RollbackChanges();

                int total = ex.InnerExceptions.Count;
                int count = 0;
                foreach (var e in ex.InnerExceptions)
                {
                    _logger.Error($"Error processing {logString} for {snapshot} ({++count}/{total})", e);
                }
                throw;
            }
            catch (Exception ex)
            {
                _marketsRuleManager.RollbackChanges();

                _logger.Error($"Error processing {logString} {snapshot}", ex);
                throw;
            }

            _logger.Info($"Finished processing {logString} for {snapshot}");
        }