示例#1
0
        public SelfRefreshingClient(string apiKey,
                                    ConfigurationOptions config,
                                    ISplitLogger log = null) : base(GetLogger(log))
        {
            _config       = (SelfRefreshingConfig)_configService.ReadConfig(config, ConfingTypes.InMemory);
            LabelsEnabled = _config.LabelsEnabled;

            ApiKey = apiKey;
            BuildSplitCache();
            BuildSegmentCache();
            BuildTelemetryStorage();
            BuildTelemetrySyncTask();
            BuildSdkApiClients();
            BuildSplitFetcher();
            BuildTreatmentLog(config);
            BuildImpressionManager();
            BuildEventLog(config);
            BuildEvaluator();
            BuildBlockUntilReadyService();
            BuildManager();
            BuildSyncManager();

            _startSessionMs = CurrentTimeHelper.CurrentTimeMillis();
            Start();
        }
        public void BuildImpressionWithDebugAndWithPreviousTime()
        {
            // Arrange.
            var impressionsManager = new ImpressionsManager(_impressionsLog.Object, _customerImpressionListener.Object, _impressionsCounter.Object, true, ImpressionsMode.Debug, _impressionsObserver.Object);
            var impTime            = CurrentTimeHelper.CurrentTimeMillis();

            _impressionsObserver
            .Setup(mock => mock.TestAndSet(It.IsAny <KeyImpression>()))
            .Returns((long?)null);

            // Act.
            var result = impressionsManager.BuildImpression("matching-key", "feature", "off", impTime, 432543, "label", "bucketing-key");

            // Assert.
            Assert.AreEqual("matching-key", result.keyName);
            Assert.AreEqual("feature", result.feature);
            Assert.AreEqual("off", result.treatment);
            Assert.AreEqual(impTime, result.time);
            Assert.AreEqual("label", result.label);
            Assert.AreEqual("bucketing-key", result.bucketingKey);
            Assert.IsNull(result.previousTime);

            _impressionsObserver.Verify(mock => mock.TestAndSet(It.IsAny <KeyImpression>()), Times.Once);
            _impressionsCounter.Verify(mock => mock.Inc("feature", impTime), Times.Never);
        }
示例#3
0
        public void TrackWithoutCustomerListener_Debug()
        {
            // Arrange.
            var impressionsObserver = new ImpressionsObserver(new ImpressionHasher());
            var impressionsCounter  = new ImpressionsCounter();
            var impressionsManager  = new ImpressionsManager(_impressionsLog.Object, null, impressionsCounter, true, ImpressionsMode.Debug, _telemetryRuntimeProducer.Object, _tasksManager, impressionsObserver);

            var impTime     = CurrentTimeHelper.CurrentTimeMillis();
            var impressions = new List <KeyImpression>
            {
                impressionsManager.BuildImpression("matching-key", "feature", "off", impTime, 432543, "label", "bucketing-key"),
                impressionsManager.BuildImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key"),
                impressionsManager.BuildImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key"),
                impressionsManager.BuildImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key")
            };

            // Act.
            impressionsManager.Track(impressions);

            // Assert.
            Thread.Sleep(1000);
            _impressionsLog.Verify(mock => mock.Log(impressions), Times.Once);
            _customerImpressionListener.Verify(mock => mock.Log(It.IsAny <KeyImpression>()), Times.Never);
            _telemetryRuntimeProducer.Verify(mock => mock.RecordImpressionsStats(ImpressionsEnum.ImpressionsDeduped, 0), Times.Once);
            _telemetryRuntimeProducer.Verify(mock => mock.RecordImpressionsStats(ImpressionsEnum.ImpressionsDropped, 0), Times.Once);
            _telemetryRuntimeProducer.Verify(mock => mock.RecordImpressionsStats(ImpressionsEnum.ImpressionsQueued, 4), Times.Once);
        }
        public void TrackWithoutCustomerListener_Optimized()
        {
            // Arrange.
            var impressionsObserver = new ImpressionsObserver(new ImpressionHasher());
            var impressionsCounter  = new ImpressionsCounter();
            var impressionsManager  = new ImpressionsManager(_impressionsLog.Object, null, impressionsCounter, true, ImpressionsMode.Optimized, impressionsObserver);

            var impTime     = CurrentTimeHelper.CurrentTimeMillis();
            var impressions = new List <KeyImpression>
            {
                impressionsManager.BuildImpression("matching-key", "feature", "off", impTime, 432543, "label", "bucketing-key"),
                impressionsManager.BuildImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key"),
                impressionsManager.BuildImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key"),
                impressionsManager.BuildImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key")
            };

            var optimizedImpressions = impressions.Where(i => impressionsManager.ShouldQueueImpression(i)).ToList();

            // Act.
            impressionsManager.Track(impressions);

            // Assert.
            Thread.Sleep(1000);
            Assert.AreEqual(2, optimizedImpressions.Count());
            _impressionsLog.Verify(mock => mock.Log(optimizedImpressions), Times.Once);
            _impressionsLog.Verify(mock => mock.Log(impressions), Times.Never);
            _customerImpressionListener.Verify(mock => mock.Log(It.IsAny <KeyImpression>()), Times.Never);
        }
示例#5
0
        public void Track_Optimized_WithOneImpressionDropped()
        {
            // Arrange.
            var impressionsManager = new ImpressionsManager(_impressionsLog.Object, _customerImpressionListener.Object, _impressionsCounter.Object, true, ImpressionsMode.Optimized, _telemetryRuntimeProducer.Object, _tasksManager, _impressionsObserver.Object);
            var impTime            = CurrentTimeHelper.CurrentTimeMillis();
            var impressions        = new List <KeyImpression>
            {
                new KeyImpression("matching-key", "feature", "off", impTime, 432543, "label", "bucketing-key", optimized: true),
                new KeyImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key", optimized: true)
            };

            _impressionsLog
            .Setup(mock => mock.Log(It.IsAny <List <KeyImpression> >()))
            .Returns(1);

            // Act.
            impressionsManager.Track(impressions);

            // Assert.
            Thread.Sleep(1000);
            _impressionsLog.Verify(mock => mock.Log(impressions), Times.Once);
            _customerImpressionListener.Verify(mock => mock.Log(It.IsAny <KeyImpression>()), Times.Exactly(2));
            _telemetryRuntimeProducer.Verify(mock => mock.RecordImpressionsStats(ImpressionsEnum.ImpressionsDeduped, 0), Times.Once);
            _telemetryRuntimeProducer.Verify(mock => mock.RecordImpressionsStats(ImpressionsEnum.ImpressionsDropped, 1), Times.Once);
            _telemetryRuntimeProducer.Verify(mock => mock.RecordImpressionsStats(ImpressionsEnum.ImpressionsQueued, 1), Times.Once);
        }
示例#6
0
        private SelfRefreshingConfig MockConfigInit()
        {
            _telemetryStorage.Setup(mock => mock.GetBURTimeouts()).Returns(2);
            _factoryInstantiationsService.Setup(mock => mock.GetActiveFactories()).Returns(5);
            _factoryInstantiationsService.Setup(mock => mock.GetRedundantActiveFactories()).Returns(8);
            _telemetryStorage.Setup(mock => mock.GetNonReadyUsages()).Returns(10);

            return(new SelfRefreshingConfig
            {
                EventLogSize = 2,
                EventLogRefreshRate = 60,
                TreatmentLogRefreshRate = 60,
                SegmentRefreshRate = 60,
                SplitsRefreshRate = 60,
                TelemetryRefreshRate = 60,
                ImpressionsMode = ImpressionsMode.Optimized,
                Mode = Splitio.Services.Client.Classes.Mode.Standalone,
                TreatmentLogSize = 4,
                SdkStartTime = CurrentTimeHelper.CurrentTimeMillis(),
                BaseUrl = "https://sdk.split.io",
                EventsBaseUrl = "https://events.split.io",
                AuthServiceURL = "https://auth.split.io",
                StreamingServiceURL = "https://streaming.split.io",
                TelemetryServiceURL = "https://telemetry.split.io"
            });
        }
示例#7
0
        public virtual bool Track(string key, string trafficType, string eventType, double?value = null, Dictionary <string, object> properties = null)
        {
            if (_statusManager.IsDestroyed())
            {
                return(false);
            }

            using (var clock = new Util.SplitStopwatch())
            {
                clock.Start();

                var keyResult             = _keyValidator.IsValid(new Key(key, null), nameof(Track));
                var eventTypeResult       = _eventTypeValidator.IsValid(eventType, nameof(eventType));
                var eventPropertiesResult = _eventPropertiesValidator.IsValid(properties);

                var trafficTypeResult = _blockUntilReadyService.IsSdkReady()
                    ? _trafficTypeValidator.IsValid(trafficType, nameof(trafficType))
                    : new ValidatorResult {
                    Success = true, Value = trafficType
                };

                if (!keyResult || !trafficTypeResult.Success || !eventTypeResult || !eventPropertiesResult.Success)
                {
                    return(false);
                }

                try
                {
                    var eventToLog = new Event
                    {
                        key             = key,
                        trafficTypeName = trafficTypeResult.Value,
                        eventTypeId     = eventType,
                        value           = value,
                        timestamp       = CurrentTimeHelper.CurrentTimeMillis(),
                        properties      = (Dictionary <string, object>)eventPropertiesResult.Value
                    };

                    _tasksManager.Start(() =>
                    {
                        _eventsLog.Log(new WrappedEvent
                        {
                            Event = eventToLog,
                            Size  = eventPropertiesResult.EventSize
                        });
                    }, new CancellationTokenSource(), "Track");

                    RecordLatency(nameof(Track), clock.ElapsedMilliseconds);

                    return(true);
                }
                catch (Exception e)
                {
                    _log.Error("Exception caught trying to track an event", e);
                    RecordException(nameof(Track));
                    return(false);
                }
            }
        }
示例#8
0
 public override void Destroy()
 {
     if (!_statusManager.IsDestroyed())
     {
         _telemetryRuntimeProducer.RecordSessionLength(CurrentTimeHelper.CurrentTimeMillis() - _startSessionMs);
         Stop();
         base.Destroy();
     }
 }
示例#9
0
        private Dictionary <string, TreatmentResult> GetTreatmentsResult(Key key, List <string> features, string operation, string method, Dictionary <string, object> attributes = null)
        {
            var treatmentsForFeatures = new Dictionary <string, TreatmentResult>();

            if (!IsClientReady(method))
            {
                foreach (var feature in features)
                {
                    treatmentsForFeatures.Add(feature, new TreatmentResult(LabelClientNotReady, Control, null));
                }

                return(treatmentsForFeatures);
            }

            var ImpressionsQueue = new List <KeyImpression>();

            if (_keyValidator.IsValid(key, method))
            {
                features = _splitNameValidator.SplitNamesAreValid(features, method);

                var start = CurrentTimeHelper.CurrentTimeMillis();
                var clock = new Stopwatch();
                clock.Start();

                foreach (var feature in features)
                {
                    var treatmentResult = DoGetTreatment(key, feature, attributes, true);

                    treatmentsForFeatures.Add(feature, treatmentResult);

                    if (!LabelSplitNotFound.Equals(treatmentResult.Label))
                    {
                        ImpressionsQueue.Add(BuildImpression(key.matchingKey, feature, treatmentResult.Treatment, start, treatmentResult.ChangeNumber, LabelsEnabled ? treatmentResult.Label : null, key.bucketingKeyHadValue ? key.bucketingKey : null));
                    }
                }

                if (metricsLog != null)
                {
                    metricsLog.Time(operation, clock.ElapsedMilliseconds);
                }

                ImpressionLog(ImpressionsQueue);
            }
            else
            {
                foreach (var feature in features)
                {
                    treatmentsForFeatures.Add(feature, new TreatmentResult(LabelSplitNotFound, Control, null));
                }
            }

            ClearItemsAddedToTreatmentCache(key?.matchingKey);

            return(treatmentsForFeatures);
        }
示例#10
0
        public virtual bool Track(string key, string trafficType, string eventType, double?value = null, Dictionary <string, object> properties = null)
        {
            if (Destroyed)
            {
                return(false);
            }

            var keyResult             = _keyValidator.IsValid(new Key(key, null), nameof(Track));
            var eventTypeResult       = _eventTypeValidator.IsValid(eventType, nameof(eventType));
            var eventPropertiesResult = _eventPropertiesValidator.IsValid(properties);

            var trafficTypeResult = _blockUntilReadyService.IsSdkReady()
                ? _trafficTypeValidator.IsValid(trafficType, nameof(trafficType))
                : new ValidatorResult {
                Success = true, Value = trafficType
            };

            if (!keyResult || !trafficTypeResult.Success || !eventTypeResult || !eventPropertiesResult.Success)
            {
                return(false);
            }

            try
            {
                var eventToLog = new Event
                {
                    key             = key,
                    trafficTypeName = trafficTypeResult.Value,
                    eventTypeId     = eventType,
                    value           = value,
                    timestamp       = CurrentTimeHelper.CurrentTimeMillis(),
                    properties      = (Dictionary <string, object>)eventPropertiesResult.Value
                };

                Task.Factory.StartNew(() =>
                {
                    _eventsLog.Log(new WrappedEvent
                    {
                        Event = eventToLog,
                        Size  = eventPropertiesResult.EventSize
                    });
                });

                return(true);
            }
            catch (Exception e)
            {
                _log.Error("Exception caught trying to track an event", e);
                return(false);
            }
        }
示例#11
0
        private TreatmentResult GetTreatmentResult(Key key, string feature, string operation, string method, Dictionary <string, object> attributes = null, bool logMetricsAndImpressions = true, bool multiple = false)
        {
            if (!IsClientReady(method))
            {
                return(new TreatmentResult(LabelClientNotReady, Control, null));
            }

            if (!_keyValidator.IsValid(key, method))
            {
                return(new TreatmentResult(LabelException, Control, null));
            }

            var splitNameResult = _splitNameValidator.SplitNameIsValid(feature, method);

            if (!splitNameResult.Success)
            {
                return(new TreatmentResult(LabelException, Control, null));
            }

            feature = splitNameResult.Value;

            var start = CurrentTimeHelper.CurrentTimeMillis();
            var clock = new Stopwatch();

            clock.Start();

            var result = DoGetTreatment(key, feature, attributes, multiple);

            if (logMetricsAndImpressions)
            {
                if (metricsLog != null)
                {
                    metricsLog.Time(operation, clock.ElapsedMilliseconds);
                }

                if (!LabelSplitNotFound.Equals(result.Label))
                {
                    ImpressionLog(new List <KeyImpression>
                    {
                        BuildImpression(key.matchingKey, feature, result.Treatment, start, result.ChangeNumber, LabelsEnabled ? result.Label : null, key.bucketingKeyHadValue ? key.bucketingKey : null)
                    });
                }
            }

            return(result);
        }
        public void BuildAndTrackWithoutCustomerListener()
        {
            // Arrange.
            var impressionsManager = new ImpressionsManager(_impressionsLog.Object, null, _impressionsCounter.Object, true, ImpressionsMode.Optimized, _impressionsObserver.Object);
            var impTime            = CurrentTimeHelper.CurrentTimeMillis();

            // Act.
            impressionsManager.BuildAndTrack("matching-key", "feature", "off", impTime, 432543, "label", "bucketing-key");

            // Assert.
            _impressionsObserver.Verify(mock => mock.TestAndSet(It.IsAny <KeyImpression>()), Times.Once);
            _impressionsCounter.Verify(mock => mock.Inc("feature", impTime), Times.Once);

            Thread.Sleep(1000);
            _impressionsLog.Verify(mock => mock.Log(It.IsAny <List <KeyImpression> >()), Times.Once);
            _customerImpressionListener.Verify(mock => mock.Log(It.IsAny <KeyImpression>()), Times.Never);
        }
示例#13
0
        private void RecordInit()
        {
            try
            {
                var config = new Config
                {
                    BURTimeouts     = _telemetryStorageConsumer.GetBURTimeouts(),
                    EventsQueueSize = _configurationOptions.EventLogSize,
                    Rates           = new Rates
                    {
                        Events      = _configurationOptions.EventLogRefreshRate,
                        Impressions = _configurationOptions.TreatmentLogRefreshRate,
                        Segments    = _configurationOptions.SegmentRefreshRate,
                        Splits      = _configurationOptions.SplitsRefreshRate,
                        Telemetry   = _configurationOptions.TelemetryRefreshRate
                    },
                    UrlOverrides = new UrlOverrides
                    {
                        Sdk       = !_configurationOptions.BaseUrl.Equals(Constants.Urls.BaseUrl),
                        Events    = !_configurationOptions.EventsBaseUrl.Equals(Constants.Urls.EventsBaseUrl),
                        Auth      = !_configurationOptions.AuthServiceURL.Equals(Constants.Urls.AuthServiceURL),
                        Stream    = !_configurationOptions.StreamingServiceURL.Equals(Constants.Urls.StreamingServiceURL),
                        Telemetry = !_configurationOptions.TelemetryServiceURL.Equals(Constants.Urls.TelemetryServiceURL)
                    },
                    StreamingEnabled          = _configurationOptions.StreamingEnabled,
                    ImpressionsMode           = _configurationOptions.ImpressionsMode,
                    ImpressionListenerEnabled = _configurationOptions.ImpressionListener != null,
                    OperationMode             = (int)_configurationOptions.Mode,
                    ImpressionsQueueSize      = _configurationOptions.TreatmentLogSize,
                    Tags = _telemetryStorageConsumer.PopTags().ToList(),
                    TimeUntilSDKReady        = CurrentTimeHelper.CurrentTimeMillis() - _configurationOptions.SdkStartTime,
                    ActiveFactories          = _factoryInstantiationsService.GetActiveFactories(),
                    RedundantActiveFactories = _factoryInstantiationsService.GetRedundantActiveFactories(),
                    Storage           = Constants.StorageType.Memory,
                    SDKNotReadyUsage  = _telemetryStorageConsumer.GetNonReadyUsages(),
                    HTTPProxyDetected = IsHTTPProxyDetected()
                };

                _telemetryAPI.RecordConfigInit(config);
            }
            catch (Exception ex)
            {
                _log.Error("Something were wrong posting Config.", ex);
            }
        }
        public void Track()
        {
            // Arrange.
            var impressionsManager = new ImpressionsManager(_impressionsLog.Object, _customerImpressionListener.Object, _impressionsCounter.Object, true, ImpressionsMode.Optimized, _impressionsObserver.Object);
            var impTime            = CurrentTimeHelper.CurrentTimeMillis();
            var impressions        = new List <KeyImpression>
            {
                new KeyImpression("matching-key", "feature", "off", impTime, 432543, "label", "bucketing-key"),
                new KeyImpression("matching-key-2", "feature-2", "off", impTime, 432543, "label-2", "bucketing-key")
            };

            // Act.
            impressionsManager.Track(impressions);

            // Assert.
            Thread.Sleep(1000);
            _impressionsLog.Verify(mock => mock.Log(impressions), Times.Once);
            _customerImpressionListener.Verify(mock => mock.Log(It.IsAny <KeyImpression>()), Times.Exactly(2));
        }
示例#15
0
        public SelfRefreshingConfig ReadInMemoryConfig(ConfigurationOptions config)
        {
            var baseConfig = ReadBaseConfig(config);

            var selfRefreshingConfig = new SelfRefreshingConfig
            {
                Mode                          = config.Mode,
                SdkVersion                    = baseConfig.SdkVersion,
                SdkMachineName                = baseConfig.SdkMachineName,
                SdkMachineIP                  = baseConfig.SdkMachineIP,
                LabelsEnabled                 = baseConfig.LabelsEnabled,
                SplitsRefreshRate             = config.FeaturesRefreshRate ?? 5,
                SegmentRefreshRate            = config.SegmentsRefreshRate ?? 60,
                HttpConnectionTimeout         = config.ConnectionTimeout ?? 15000,
                HttpReadTimeout               = config.ReadTimeout ?? 15000,
                RandomizeRefreshRates         = config.RandomizeRefreshRates, ConcurrencyLevel = config.SplitsStorageConcurrencyLevel ?? 4,
                TreatmentLogSize              = config.MaxImpressionsLogSize ?? 30000,
                ImpressionsBulkSize           = 5000,
                EventLogRefreshRate           = config.EventsPushRate ?? 60,
                EventLogSize                  = config.EventsQueueSize ?? 10000,
                EventsBulkSize                = 500,
                EventsFirstPushWindow         = config.EventsFirstPushWindow ?? 10,
                NumberOfParalellSegmentTasks  = config.NumberOfParalellSegmentTasks ?? 5,
                StreamingEnabled              = config.StreamingEnabled ?? true,
                AuthRetryBackoffBase          = GetMinimunAllowed(config.AuthRetryBackoffBase ?? 1, 1, "AuthRetryBackoffBase"),
                StreamingReconnectBackoffBase = GetMinimunAllowed(config.StreamingReconnectBackoffBase ?? 1, 1, "StreamingReconnectBackoffBase"),
                ImpressionsMode               = config.ImpressionsMode ?? ImpressionsMode.Optimized,
                TelemetryRefreshRate          = GetMinimunAllowed(config.TelemetryRefreshRate ?? 3600, 60, "TelemetryRefreshRate"),
                ImpressionListener            = config.ImpressionListener,
                AuthServiceURL                = string.IsNullOrEmpty(config.AuthServiceURL) ? Constants.Urls.AuthServiceURL : config.AuthServiceURL,
                BaseUrl                       = string.IsNullOrEmpty(config.Endpoint) ? Constants.Urls.BaseUrl : config.Endpoint,
                EventsBaseUrl                 = string.IsNullOrEmpty(config.EventsEndpoint) ? Constants.Urls.EventsBaseUrl : config.EventsEndpoint,
                StreamingServiceURL           = string.IsNullOrEmpty(config.StreamingServiceURL) ? Constants.Urls.StreamingServiceURL : config.StreamingServiceURL,
                TelemetryServiceURL           = string.IsNullOrEmpty(config.TelemetryServiceURL) ? Constants.Urls.TelemetryServiceURL : config.TelemetryServiceURL,
                SdkStartTime                  = CurrentTimeHelper.CurrentTimeMillis(),
                OnDemandFetchMaxRetries       = 10,
                OnDemandFetchRetryDelayMs     = 50
            };

            selfRefreshingConfig.TreatmentLogRefreshRate = GetImpressionRefreshRate(selfRefreshingConfig.ImpressionsMode, config.ImpressionsRefreshRate);

            return(selfRefreshingConfig);
        }
示例#16
0
        protected override string GetTreatmentForFeature(Key key, string feature, Dictionary <string, object> attributes = null, bool logMetricsAndImpressions = true)
        {
            long start = CurrentTimeHelper.CurrentTimeMillis();
            var  clock = new Stopwatch();

            clock.Start();

            try
            {
                var split = splitCache.GetSplit(feature);

                if (split == null)
                {
                    if (logMetricsAndImpressions)
                    {
                        //if split definition was not found, impression label = "rules not found"
                        RecordStats(key, feature, null, LabelSplitNotFound, start, Control, SdkGetTreatment, clock);
                    }

                    Log.Warn(String.Format("Unknown or invalid feature: {0}", feature));
                    return(Control);
                }

                ParsedSplit parsedSplit = splitParser.Parse((Split)split);

                var treatment = GetTreatment(key, parsedSplit, attributes, start, clock, this, logMetricsAndImpressions);

                return(treatment);
            }
            catch (Exception e)
            {
                if (logMetricsAndImpressions)
                {
                    //if there was an exception, impression label = "exception"
                    RecordStats(key, feature, null, LabelException, start, Control, SdkGetTreatment, clock);
                }

                Log.Error(String.Format("Exception caught getting treatment for feature: {0}", feature), e);
                return(Control);
            }
        }
示例#17
0
        private TreatmentResult GetTreatmentResult(Key key, string feature, string operation, string method, Dictionary <string, object> attributes = null)
        {
            if (!IsClientReady(method))
            {
                return(new TreatmentResult(string.Empty, Control, null));
            }

            if (!_keyValidator.IsValid(key, method))
            {
                return(new TreatmentResult(string.Empty, Control, null));
            }

            var splitNameResult = _splitNameValidator.SplitNameIsValid(feature, method);

            if (!splitNameResult.Success)
            {
                return(new TreatmentResult(string.Empty, Control, null));
            }

            feature = splitNameResult.Value;

            var result = _evaluator.EvaluateFeature(key, feature, attributes);

            if (_metricsLog != null)
            {
                _metricsLog.Time(operation, result.ElapsedMilliseconds);
            }

            if (!Labels.SplitNotFound.Equals(result.Label))
            {
                ImpressionLog(new List <KeyImpression>
                {
                    BuildImpression(key.matchingKey, feature, result.Treatment, CurrentTimeHelper.CurrentTimeMillis(), result.ChangeNumber, LabelsEnabled ? result.Label : null, key.bucketingKeyHadValue ? key.bucketingKey : null)
                });
            }

            return(result);
        }
示例#18
0
        public async Task <string> FetchSplitChanges(long since, FetchOptions fetchOptions)
        {
            using (var clock = new Util.SplitStopwatch())
            {
                clock.Start();

                try
                {
                    var requestUri = GetRequestUri(since, fetchOptions.Till);
                    var response   = await ExecuteGet(requestUri, fetchOptions.CacheControlHeaders);

                    if ((int)response.statusCode >= (int)HttpStatusCode.OK && (int)response.statusCode < (int)HttpStatusCode.Ambiguous)
                    {
                        _telemetryRuntimeProducer.RecordSyncLatency(ResourceEnum.SplitSync, Util.Metrics.Bucket(clock.ElapsedMilliseconds));
                        _telemetryRuntimeProducer.RecordSuccessfulSync(ResourceEnum.SplitSync, CurrentTimeHelper.CurrentTimeMillis());

                        return(response.content);
                    }

                    _log.Error($"Http status executing FetchSplitChanges: {response.statusCode.ToString()} - {response.content}");

                    _telemetryRuntimeProducer.RecordSyncError(ResourceEnum.SplitSync, (int)response.statusCode);

                    return(string.Empty);
                }
                catch (Exception e)
                {
                    _log.Error("Exception caught executing FetchSplitChanges", e);

                    return(string.Empty);
                }
            }
        }
示例#19
0
        private TreatmentResult GetTreatmentResult(Key key, string feature, string method, Dictionary <string, object> attributes = null)
        {
            if (!IsClientReady(method))
            {
                return(new TreatmentResult(string.Empty, Control, null));
            }

            if (!_keyValidator.IsValid(key, method))
            {
                return(new TreatmentResult(string.Empty, Control, null));
            }

            var splitNameResult = _splitNameValidator.SplitNameIsValid(feature, method);

            if (!splitNameResult.Success)
            {
                return(new TreatmentResult(string.Empty, Control, null));
            }

            feature = splitNameResult.Value;

            var result = _evaluator.EvaluateFeature(key, feature, attributes);

            if (result.Exception)
            {
                RecordException(method);
            }

            RecordLatency(method, result.ElapsedMilliseconds);

            if (!Labels.SplitNotFound.Equals(result.Label))
            {
                _impressionsManager.BuildAndTrack(key.matchingKey, feature, result.Treatment, CurrentTimeHelper.CurrentTimeMillis(), result.ChangeNumber, LabelsEnabled ? result.Label : null, key.bucketingKeyHadValue ? key.bucketingKey : null);
            }

            return(result);
        }
示例#20
0
 private long CalcularteNextTokenExpiration(double time)
 {
     return(CurrentTimeHelper.CurrentTimeMillis() + Convert.ToInt64(time * 1000));
 }
示例#21
0
 public StreamingEvent(EventTypeEnum type)
 {
     Timestamp = CurrentTimeHelper.CurrentTimeMillis();
     Type      = (int)type;
 }
示例#22
0
        public async Task <string> FetchSegmentChanges(string name, long since, FetchOptions fetchOptions)
        {
            using (var clock = new Util.SplitStopwatch())
            {
                clock.Start();

                try
                {
                    var requestUri = GetRequestUri(name, since, fetchOptions.Till);
                    var response   = await ExecuteGet(requestUri, fetchOptions.CacheControlHeaders);

                    if ((int)response.statusCode >= (int)HttpStatusCode.OK && (int)response.statusCode < (int)HttpStatusCode.Ambiguous)
                    {
                        if (_log.IsDebugEnabled)
                        {
                            _log.Debug($"FetchSegmentChanges with name '{name}' took {clock.ElapsedMilliseconds} milliseconds using uri '{requestUri}'");
                        }

                        _telemetryRuntimeProducer.RecordSyncLatency(ResourceEnum.SegmentSync, Util.Metrics.Bucket(clock.ElapsedMilliseconds));
                        _telemetryRuntimeProducer.RecordSuccessfulSync(ResourceEnum.SegmentSync, CurrentTimeHelper.CurrentTimeMillis());

                        return(response.content);
                    }

                    _log.Error(response.statusCode == HttpStatusCode.Forbidden
                        ? "factory instantiation: you passed a browser type api_key, please grab an api key from the Split console that is of type sdk"
                        : $"Http status executing FetchSegmentChanges: {response.statusCode.ToString()} - {response.content}");

                    _telemetryRuntimeProducer.RecordSyncError(ResourceEnum.SegmentSync, (int)response.statusCode);

                    return(string.Empty);
                }
                catch (Exception e)
                {
                    _log.Error("Exception caught executing FetchSegmentChanges", e);

                    return(string.Empty);
                }
            }
        }
示例#23
0
        private async Task ExecutePost(string url, object data, string method)
        {
            var jsonData = JsonConvert.SerializeObject(data, new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore
            });

            var response = await _splitioHttpClient.PostAsync($"{_telemetryURL}{url}", jsonData);

            if ((int)response.statusCode >= (int)HttpStatusCode.OK && (int)response.statusCode < (int)HttpStatusCode.Ambiguous)
            {
                _telemetryRuntimeProducer.RecordSuccessfulSync(ResourceEnum.TelemetrySync, CurrentTimeHelper.CurrentTimeMillis());
                _log.Debug($"Telemetry post success. {method}");
            }
            else
            {
                _log.Error($"Http status executing {method}: {response.statusCode} - {response.content}");
                _telemetryRuntimeProducer.RecordSyncError(ResourceEnum.TelemetrySync, (int)response.statusCode);
            }
        }
示例#24
0
        public async Task <AuthenticationResponse> AuthenticateAsync()
        {
            using (var clock = new Util.SplitStopwatch())
            {
                clock.Start();

                try
                {
                    var response = await _splitioHttpClient.GetAsync(_url);

                    if (response.statusCode == HttpStatusCode.OK)
                    {
                        _log.Debug($"Success connection to: {_url}");

                        _telemetryRuntimeProducer.RecordSyncLatency(ResourceEnum.TokenSync, Util.Metrics.Bucket(clock.ElapsedMilliseconds));
                        _telemetryRuntimeProducer.RecordSuccessfulSync(ResourceEnum.TokenSync, CurrentTimeHelper.CurrentTimeMillis());

                        return(GetSuccessResponse(response.content));
                    }
                    else if (response.statusCode >= HttpStatusCode.BadRequest && response.statusCode < HttpStatusCode.InternalServerError)
                    {
                        _log.Debug($"Problem to connect to : {_url}. Response status: {response.statusCode}");

                        _telemetryRuntimeProducer.RecordAuthRejections();
                        return(new AuthenticationResponse {
                            PushEnabled = false, Retry = false
                        });
                    }

                    _telemetryRuntimeProducer.RecordSyncError(ResourceEnum.TokenSync, (int)response.statusCode);
                    return(new AuthenticationResponse {
                        PushEnabled = false, Retry = true
                    });
                }
                catch (Exception ex)
                {
                    _log.Error(ex.Message);

                    return(new AuthenticationResponse {
                        PushEnabled = false, Retry = false
                    });
                }
            }
        }
示例#25
0
        private Dictionary <string, TreatmentResult> GetTreatmentsResult(Key key, List <string> features, string method, Dictionary <string, object> attributes = null)
        {
            var treatmentsForFeatures = new Dictionary <string, TreatmentResult>();

            if (!IsClientReady(method))
            {
                foreach (var feature in features)
                {
                    treatmentsForFeatures.Add(feature, new TreatmentResult(string.Empty, Control, null));
                }

                return(treatmentsForFeatures);
            }

            var ImpressionsQueue = new List <KeyImpression>();

            if (_keyValidator.IsValid(key, method))
            {
                features = _splitNameValidator.SplitNamesAreValid(features, method);

                var results = _evaluator.EvaluateFeatures(key, features, attributes);

                foreach (var treatmentResult in results.TreatmentResults)
                {
                    treatmentsForFeatures.Add(treatmentResult.Key, treatmentResult.Value);

                    if (!Labels.SplitNotFound.Equals(treatmentResult.Value.Label))
                    {
                        ImpressionsQueue.Add(_impressionsManager.BuildImpression(key.matchingKey, treatmentResult.Key, treatmentResult.Value.Treatment, CurrentTimeHelper.CurrentTimeMillis(), treatmentResult.Value.ChangeNumber, LabelsEnabled ? treatmentResult.Value.Label : null, key.bucketingKeyHadValue ? key.bucketingKey : null));
                    }
                }

                if (results.Exception)
                {
                    RecordException(method);
                }

                RecordLatency(method, results.ElapsedMilliseconds);

                _impressionsManager.Track(ImpressionsQueue);
            }
            else
            {
                foreach (var feature in features)
                {
                    treatmentsForFeatures.Add(feature, new TreatmentResult(string.Empty, Control, null));
                }
            }

            return(treatmentsForFeatures);
        }
示例#26
0
 public StreamingEvent(EventTypeEnum type, long data)
 {
     Timestamp = CurrentTimeHelper.CurrentTimeMillis();
     Type      = (int)type;
     Data      = data;
 }