Skip to content
4 changes: 1 addition & 3 deletions Splitio.Redis/Services/Client/Classes/RedisClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@ public class RedisClient : SplitClient
private IImpressionsCache _impressionsCache;
private ConnectionPoolManager _connectionPoolManager;
private IFeatureFlagCacheConsumer _featureFlagCacheConsumer;
private readonly new FallbackTreatmentCalculator _fallbackTreatmentCalculator;

public RedisClient(ConfigurationOptions config, string apiKey, FallbackTreatmentCalculator fallbackTreatmentCalculator) : base(apiKey, fallbackTreatmentCalculator)
public RedisClient(ConfigurationOptions config, string apiKey) : base(apiKey, config)
{
_config = new RedisConfig();
_fallbackTreatmentCalculator = fallbackTreatmentCalculator;

ReadConfig(config);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Splitio.Services.Cache.Interfaces;
using Splitio.Domain;
using Splitio.Services.Cache.Interfaces;
using Splitio.Services.Common;
using System.Collections.Generic;
using System.Threading;

namespace Splitio.Services.Client.Classes
Expand All @@ -7,6 +10,12 @@ public class InMemoryReadinessGatesCache : IStatusManager
{
private readonly CountdownEvent _sdkReady = new CountdownEvent(1);
private readonly CountdownEvent _sdkDestroyed = new CountdownEvent(1);
private readonly IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;

public InMemoryReadinessGatesCache(IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> eventsManager)
{
_eventsManager = eventsManager;
}

public bool IsReady()
{
Expand All @@ -21,6 +30,8 @@ public bool WaitUntilReady(int milliseconds)
public void SetReady()
{
_sdkReady.Signal();
_eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady,
new EventMetadata(new Dictionary<string, object>()));
}

public void SetDestroy()
Expand Down
13 changes: 6 additions & 7 deletions src/Splitio/Services/Client/Classes/JSONFileClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class JSONFileClient : SplitClient

public JSONFileClient(string splitsFilePath,
string segmentsFilePath,
FallbackTreatmentCalculator fallbackTreatmentCalculator,
ConfigurationOptions config,
ISegmentCache segmentCacheInstance = null,
IFeatureFlagCache featureFlagCacheInstance = null,
IImpressionsLog impressionsLog = null,
Expand All @@ -33,11 +33,10 @@ public JSONFileClient(string splitsFilePath,
ITrafficTypeValidator trafficTypeValidator = null,
IImpressionsManager impressionsManager = null,
IRuleBasedSegmentCache ruleBasedSegmentCache = null
) : base("localhost", fallbackTreatmentCalculator)
) : base("localhost", config)
{
var eventsManager = new EventsManager<SdkEvent, SdkInternalEvent, EventMetadata>(new EventsManagerConfig(), new EventDelivery<SdkEvent, EventMetadata>());
_segmentCache = segmentCacheInstance ?? new InMemorySegmentCache(new ConcurrentDictionary<string, Segment>(), eventsManager);
var rbsCache = ruleBasedSegmentCache ?? new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary<string, RuleBasedSegment>(), eventsManager);
_segmentCache = segmentCacheInstance ?? new InMemorySegmentCache(new ConcurrentDictionary<string, Segment>(), _eventsManager);
var rbsCache = ruleBasedSegmentCache ?? new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary<string, RuleBasedSegment>(), _eventsManager);

var segmentFetcher = new JSONFileSegmentFetcher(segmentsFilePath, _segmentCache);
var splitChangeFetcher = new JSONFileSplitChangeFetcher(splitsFilePath);
Expand All @@ -55,13 +54,13 @@ public JSONFileClient(string splitsFilePath,
}

BuildFlagSetsFilter(new HashSet<string>());
_featureFlagCache = featureFlagCacheInstance ?? new InMemorySplitCache(new ConcurrentDictionary<string, ParsedSplit>(parsedSplits), _flagSetsFilter, eventsManager);
_featureFlagCache = featureFlagCacheInstance ?? new InMemorySplitCache(new ConcurrentDictionary<string, ParsedSplit>(parsedSplits), _flagSetsFilter, _eventsManager);
_impressionsLog = impressionsLog;
_eventsLog = eventsLog;
_trafficTypeValidator = trafficTypeValidator;
_blockUntilReadyService = new NoopBlockUntilReadyService();
_manager = new SplitManager(_featureFlagCache, _blockUntilReadyService);
_evaluator = new Evaluator.Evaluator(_featureFlagCache, new Splitter(), null, fallbackTreatmentCalculator);
_evaluator = new Evaluator.Evaluator(_featureFlagCache, new Splitter(), null, _fallbackTreatmentCalculator);
_uniqueKeysTracker = new NoopUniqueKeysTracker();
_impressionsCounter = new NoopImpressionsCounter();
_impressionsObserver = new NoopImpressionsObserver();
Expand Down
8 changes: 3 additions & 5 deletions src/Splitio/Services/Client/Classes/LocalhostClient.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Splitio.Domain;
using Splitio.Services.Cache.Classes;
using Splitio.Services.Cache.Interfaces;
using Splitio.Services.Common;
using Splitio.Services.EngineEvaluator;
using Splitio.Services.Impressions.Classes;
using Splitio.Services.InputValidation.Classes;
Expand All @@ -28,7 +27,7 @@ public class LocalhostClient : SplitClient

private readonly object _lock = new object();

public LocalhostClient(ConfigurationOptions configurationOptions, FallbackTreatmentCalculator fallbackTreatmentCalculator) : base("localhost", fallbackTreatmentCalculator)
public LocalhostClient(ConfigurationOptions configurationOptions) : base("localhost", configurationOptions)
{
var configs = (LocalhostClientConfigurations)_configService.ReadConfig(configurationOptions, ConfigTypes.Localhost, _statusManager);

Expand All @@ -47,9 +46,8 @@ public LocalhostClient(ConfigurationOptions configurationOptions, FallbackTreatm

BuildFlagSetsFilter(new HashSet<string>());

var eventsManager = new EventsManager<SdkEvent, SdkInternalEvent, EventMetadata>(new EventsManagerConfig(), new EventDelivery<SdkEvent, EventMetadata>());
var splits = _localhostFileService.ParseSplitFile(_fullPath);
_featureFlagCache = new InMemorySplitCache(splits, _flagSetsFilter, eventsManager);
_featureFlagCache = new InMemorySplitCache(splits, _flagSetsFilter, _eventsManager);


if (configs.FileSync != null)
Expand All @@ -64,7 +62,7 @@ public LocalhostClient(ConfigurationOptions configurationOptions, FallbackTreatm
_blockUntilReadyService = new NoopBlockUntilReadyService();
_manager = new SplitManager(_featureFlagCache, _blockUntilReadyService);
_trafficTypeValidator = new TrafficTypeValidator(_featureFlagCache, _blockUntilReadyService);
_evaluator = new Evaluator.Evaluator(_featureFlagCache, new Splitter(), null, fallbackTreatmentCalculator);
_evaluator = new Evaluator.Evaluator(_featureFlagCache, new Splitter(), null, _fallbackTreatmentCalculator);
_uniqueKeysTracker = new NoopUniqueKeysTracker();
_impressionsCounter = new NoopImpressionsCounter();
_impressionsObserver = new NoopImpressionsObserver();
Expand Down
13 changes: 2 additions & 11 deletions src/Splitio/Services/Client/Classes/SelfRefreshingClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,12 @@ public class SelfRefreshingClient : SplitClient
private IUpdater<Split> _featureFlagUpdater;
private IRuleBasedSegmentCache _ruleBasedSegmentCache;
private IUpdater<RuleBasedSegmentDto> _ruleBasedSegmentUpdater;
private readonly new FallbackTreatmentCalculator _fallbackTreatmentCalculator;
private EventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;

public SelfRefreshingClient(string apiKey, ConfigurationOptions config,
FallbackTreatmentCalculator fallbackTreatmentCalculator) : base(apiKey, fallbackTreatmentCalculator)
public SelfRefreshingClient(string apiKey, ConfigurationOptions config) : base(apiKey, config)
{
_config = (SelfRefreshingConfig)_configService.ReadConfig(config, ConfigTypes.InMemory);
_fallbackTreatmentCalculator = fallbackTreatmentCalculator;

BuildFlagSetsFilter(_config.FlagSetsFilter);
BuildEventsManager();
BuildSplitCache();
BuildSegmentCache();
BuildRuleBasedSegmentCache();
Expand Down Expand Up @@ -90,10 +85,6 @@ public SelfRefreshingClient(string apiKey, ConfigurationOptions config,
}

#region Private Methods
private void BuildEventsManager()
{
_eventsManager = new EventsManager<SdkEvent, SdkInternalEvent, EventMetadata>(new EventsManagerConfig(), new EventDelivery<SdkEvent, EventMetadata>());
}
private void BuildSplitCache()
{
_featureFlagCache = new InMemorySplitCache(new ConcurrentDictionary<string, ParsedSplit>(_config.ConcurrencyLevel, InitialCapacity), _flagSetsFilter, _eventsManager);
Expand Down Expand Up @@ -218,7 +209,7 @@ private void BuildManager()

private void BuildBlockUntilReadyService()
{
_blockUntilReadyService = new SelfRefreshingBlockUntilReadyService(_statusManager, _telemetryInitProducer);
_blockUntilReadyService = new SelfRefreshingBlockUntilReadyService(_statusManager, _telemetryInitProducer, _eventsManager);
}

private void BuildTelemetrySyncTask()
Expand Down
27 changes: 24 additions & 3 deletions src/Splitio/Services/Client/Classes/SplitClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,22 @@ public abstract class SplitClient : ISplitClient
protected IImpressionsObserver _impressionsObserver;
protected IClientExtensionService _clientExtensionService;
protected IFlagSetsFilter _flagSetsFilter;
protected IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;

public event EventHandler<EventMetadata> SdkReady;
public event EventHandler<EventMetadata> SdkUpdate;
public event EventHandler<EventMetadata> SdkTimedOut;

protected SplitClient(string apikey, FallbackTreatmentCalculator fallbackTreatmentCalculator)
protected SplitClient(string apikey, ConfigurationOptions options)
{
ApiKey = apikey;
_fallbackTreatmentCalculator = new FallbackTreatmentCalculator(options.FallbackTreatments);
_eventsManager = new EventsManager<SdkEvent, SdkInternalEvent, EventMetadata>(new EventsManagerConfig(), new EventDelivery<SdkEvent, EventMetadata>());

_eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReadyEvent);
_eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdateEvent);
_eventsManager.Register(SdkEvent.SdkReadyTimeout, TriggerSdkTimeoutEvent);

_fallbackTreatmentCalculator = fallbackTreatmentCalculator;
_wrapperAdapter = WrapperAdapter.Instance();
_keyValidator = new KeyValidator();
_splitNameValidator = new SplitNameValidator();
Expand All @@ -81,7 +87,7 @@ protected SplitClient(string apikey, FallbackTreatmentCalculator fallbackTreatme
_factoryInstantiationsService = FactoryInstantiationsService.Instance();
_flagSetsValidator = new FlagSetsValidator();
_configService = new ConfigService(_wrapperAdapter, _flagSetsValidator, new SdkMetadataValidator());
_statusManager = new InMemoryReadinessGatesCache();
_statusManager = new InMemoryReadinessGatesCache(_eventsManager);
_tasksManager = new TasksManager(_statusManager);
}

Expand Down Expand Up @@ -573,6 +579,21 @@ private static SplitResult TreatmentWithConfig(List<TreatmentResult> results)

return new SplitResult(result.Treatment, result.Config);
}

private void TriggerSdkReadyEvent(EventMetadata metadata)
{
SdkReady?.Invoke(this, metadata);
}

private void TriggerSdkUpdateEvent(EventMetadata metadata)
{
SdkUpdate?.Invoke(this, metadata);
}

private void TriggerSdkTimeoutEvent(EventMetadata metadata)
{
SdkTimedOut?.Invoke(this, metadata);
}
#endregion
}
}
8 changes: 3 additions & 5 deletions src/Splitio/Services/Client/Classes/SplitFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Splitio.Domain;
using Splitio.Services.Client.Interfaces;
using Splitio.Services.Impressions.Classes;
using Splitio.Services.InputValidation.Classes;
using Splitio.Services.InputValidation.Interfaces;
using Splitio.Services.Shared.Classes;
Expand Down Expand Up @@ -58,19 +57,18 @@ public ISplitManager Manager()

private void BuildSplitClient()
{
FallbackTreatmentCalculator fallbackTreatmentCalculator = new FallbackTreatmentCalculator(_options.FallbackTreatments);
switch (_options.Mode)
{
case Mode.Standalone:
_apiKeyValidator.Validate(_apiKey);

if (_apiKey == "localhost")
{
_client = new LocalhostClient(_options, fallbackTreatmentCalculator);
_client = new LocalhostClient(_options);
}
else
{
_client = new SelfRefreshingClient(_apiKey, _options, fallbackTreatmentCalculator);
_client = new SelfRefreshingClient(_apiKey, _options);
}
break;
case Mode.Consumer:
Expand All @@ -81,7 +79,7 @@ private void BuildSplitClient()
var redisAssembly = Assembly.Load(new AssemblyName("Splitio.Redis"));
var redisType = redisAssembly.GetType("Splitio.Redis.Services.Client.Classes.RedisClient");

_client = (ISplitClient)Activator.CreateInstance(redisType, new object[] { _options, _apiKey, fallbackTreatmentCalculator });
_client = (ISplitClient)Activator.CreateInstance(redisType, new object[] { _options, _apiKey });
}
catch (ArgumentException ex)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Splitio/Services/Common/EventDelivery.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Splitio.Services.Logger;
using Splitio.Domain;
using Splitio.Services.Logger;
using Splitio.Services.Shared.Classes;
using System;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using Splitio.Services.Cache.Interfaces;
using Splitio.Domain;
using Splitio.Services.Cache.Interfaces;
using Splitio.Services.Common;
using Splitio.Services.Logger;
using Splitio.Services.Shared.Interfaces;
using Splitio.Telemetry.Storages;
using System;
using System.Collections.Generic;

namespace Splitio.Services.Shared.Classes
{
Expand All @@ -12,11 +15,14 @@ public class SelfRefreshingBlockUntilReadyService : IBlockUntilReadyService

private readonly IStatusManager _statusManager;
private readonly ITelemetryInitProducer _telemetryInitProducer;
private readonly IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;

public SelfRefreshingBlockUntilReadyService(IStatusManager statusManager, ITelemetryInitProducer telemetryInitProducer)
public SelfRefreshingBlockUntilReadyService(IStatusManager statusManager, ITelemetryInitProducer telemetryInitProducer,
IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> eventsManager)
{
_statusManager = statusManager;
_telemetryInitProducer = telemetryInitProducer;
_eventsManager = eventsManager;
}

public void BlockUntilReady(int blockMilisecondsUntilReady)
Expand All @@ -30,6 +36,8 @@ public void BlockUntilReady(int blockMilisecondsUntilReady)

if (!_statusManager.WaitUntilReady(blockMilisecondsUntilReady))
{
_eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkTimedOut,
new EventMetadata(new Dictionary<string, object>()));
_telemetryInitProducer.RecordBURTimeout();
throw new TimeoutException($"SDK was not ready in {blockMilisecondsUntilReady} milliseconds");
}
Expand Down
Loading