Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions src/Splitio/Services/Client/Classes/SplitClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,24 @@ public abstract class SplitClient : ISplitClient
protected IImpressionsObserver _impressionsObserver;
protected IClientExtensionService _clientExtensionService;
protected IFlagSetsFilter _flagSetsFilter;
protected IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;
public IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;
private EventHandler<EventMetadata> SdkReadyEvent;
public event EventHandler<EventMetadata> SdkReady
{
add
{
SdkReadyEvent = (EventHandler<EventMetadata>)Delegate.Combine(SdkReadyEvent, value);
if (_eventsManager.EventAlreadyTriggered(SdkEvent.SdkReady))
{
SdkReadyEvent.Invoke(this, null);
}
}

public event EventHandler<EventMetadata> SdkReady;
remove
{
SdkReadyEvent = (EventHandler<EventMetadata>)Delegate.Remove(SdkReadyEvent, value);
}
}
public event EventHandler<EventMetadata> SdkUpdate;
public event EventHandler<EventMetadata> SdkTimedOut;

Expand All @@ -74,11 +89,8 @@ 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);

RegisterEvents();

_wrapperAdapter = WrapperAdapter.Instance();
_keyValidator = new KeyValidator();
_splitNameValidator = new SplitNameValidator();
Expand Down Expand Up @@ -309,6 +321,7 @@ public virtual async Task DestroyAsync()
_factoryInstantiationsService.Decrease(ApiKey);
_statusManager.SetDestroy();
await _syncManager.ShutdownAsync();
UnregisterEvents();

_log.Info(Messages.Destroyed);
}
Expand All @@ -322,6 +335,7 @@ public virtual void Destroy()
_factoryInstantiationsService.Decrease(ApiKey);
_statusManager.SetDestroy();
_syncManager.Shutdown();
UnregisterEvents();

_log.Info(Messages.Destroyed);
}
Expand Down Expand Up @@ -492,6 +506,18 @@ private async Task TrackImpressionsAsync(List<TreatmentResult> evaluatorResults,
#endregion

#region Private Methods
private void RegisterEvents()
{
_eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReady);
_eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdate);
_eventsManager.Register(SdkEvent.SdkReadyTimeout, TriggerSdkTimeout);
}
private void UnregisterEvents()
{
_eventsManager.Unregister(SdkEvent.SdkReady);
_eventsManager.Unregister(SdkEvent.SdkUpdate);
_eventsManager.Unregister(SdkEvent.SdkReadyTimeout);
}
private List<TreatmentResult> GetTreatmentsSync(Enums.API method, Key key, List<string> features, Dictionary<string, object> attributes = null, EvaluationOptions evaluationOptions = null)
{
try
Expand Down Expand Up @@ -580,19 +606,19 @@ private static SplitResult TreatmentWithConfig(List<TreatmentResult> results)
return new SplitResult(result.Treatment, result.Config);
}

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

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

private void TriggerSdkTimeoutEvent(EventMetadata metadata)
private void TriggerSdkTimeout(EventMetadata metaData)
{
SdkTimedOut?.Invoke(this, metadata);
SdkTimedOut?.Invoke(this, metaData);
}
#endregion
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Splitio.Services.Impressions.Interfaces;
using Splitio.Services.Tasks;
using Splitio.Telemetry.Domain;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
Expand Down Expand Up @@ -51,8 +52,7 @@ public async Task PeriodicTask_ShouldSendBulk()
// Assert.
Assert.IsTrue(_uniqueKeysTracker.Track("key-test", "feature-name-test"));

Thread.Sleep(2000);

System.Threading.SpinWait.SpinUntil(() => _cache.Count == 0, TimeSpan.FromMilliseconds(2000));
_senderAdapter.Verify(mock => mock.RecordUniqueKeysAsync(It.IsAny<List<Mtks>>()), Times.Once);

Assert.IsTrue(_uniqueKeysTracker.Track("key-test", "feature-name-test"));
Expand Down Expand Up @@ -104,7 +104,7 @@ public void Track_WithFullSize_ShouldSendTwoBulk()
Thread.Sleep(1000);
Assert.IsTrue(_uniqueKeysTracker.Track("key-test-2", "feature-name-test-6"));

Thread.Sleep(3000);
System.Threading.SpinWait.SpinUntil(() => _cache.Count==0, TimeSpan.FromMilliseconds(3000));
_senderAdapter.Verify(mock => mock.RecordUniqueKeysAsync(It.IsAny<List<Mtks>>()), Times.Exactly(2));

_cache.Clear();
Expand Down Expand Up @@ -143,8 +143,8 @@ public void Track_WithFullSize_ShouldSplitBulks()
Assert.IsTrue(_uniqueKeysTracker2.Track("key-test-4", "feature-name-test-2"));
Assert.IsTrue(_uniqueKeysTracker2.Track("key-test-5", "feature-name-test-2"));
Assert.IsTrue(_uniqueKeysTracker2.Track("key-test-6", "feature-name-test-2"));
Thread.Sleep(1000);

System.Threading.SpinWait.SpinUntil(() => _cache2.Count == 0, TimeSpan.FromMilliseconds(3000));
_senderAdapter2.Verify(mock => mock.RecordUniqueKeysAsync(It.IsAny<List<Mtks>>()), Times.Exactly(4));

_cache2.Clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Splitio.Services.Shared.Classes;
using Splitio.Services.SplitFetcher.Interfaces;
using Splitio.Services.Tasks;
using Splitio.Telemetry.Domain;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
Expand All @@ -26,12 +27,12 @@ public class SelfRefreshingSegmentFetcherUnitTests
public void InitializeSegmentNotExistent()
{
// Arrange
var gates = new InMemoryReadinessGatesCache(new EventsManager<SdkEvent,SdkInternalEvent,EventMetadata>(new EventsManagerConfig(), new EventDelivery<SdkEvent, EventMetadata>()));
Mock<IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata>> eventsManager = new Mock<IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata>>();
var gates = new InMemoryReadinessGatesCache(eventsManager.Object);
gates.SetReady();
var apiClient = new Mock<ISegmentSdkApiClient>();
var apiFetcher = new ApiSegmentChangeFetcher(apiClient.Object);
var segments = new ConcurrentDictionary<string, Segment>();
Mock<IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata>> eventsManager = new Mock<IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata>>();
var cache = new InMemorySegmentCache(segments, eventsManager.Object);
var segmentsQueue = new SplitQueue<SelfRefreshingSegment>();
var taskManager = new TasksManager(gates);
Expand Down
15 changes: 12 additions & 3 deletions tests/Splitio.Integration-tests/PollingClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Splitio.Integration_tests
public class PollingClientTests : BaseIntegrationTests
{
private static readonly HttpClientMock httpClientMock = new HttpClientMock("PollingClientTests");
private bool SdkTimeout = false;

public PollingClientTests() : base("Polling")
{ }
Expand Down Expand Up @@ -161,7 +162,8 @@ public void GetTreatment_WithtBUR_ReturnsTimeOutException()
var apikey = "apikey5";

var splitFactory = new SplitFactory(apikey, configurations);
var client = splitFactory.Client();
var client = (SplitClient)splitFactory.Client();
client.SdkTimedOut += sdkTimeout_callback;

// Act.
var exceptionMessage = "";
Expand All @@ -178,6 +180,7 @@ public void GetTreatment_WithtBUR_ReturnsTimeOutException()
}

// Assert.
Assert.IsTrue(SdkTimeout);
Assert.IsFalse(isSdkReady);
Assert.AreEqual("SDK was not ready in 0 milliseconds", exceptionMessage);

Expand Down Expand Up @@ -400,7 +403,7 @@ public void Telemetry_ValidatesConfigInitAndStats()

try
{
client.BlockUntilReady(0);
client.BlockUntilReady(1);
}
catch
{
Expand All @@ -412,7 +415,8 @@ public void Telemetry_ValidatesConfigInitAndStats()

// Assert.
Assert.AreEqual("on", result);


System.Threading.SpinWait.SpinUntil(() => (GetMetricsConfigSentBackend(httpClientMock) != null) , TimeSpan.FromMilliseconds(1000));
var sentConfig = GetMetricsConfigSentBackend(httpClientMock);
Assert.IsNotNull(sentConfig);
Assert.AreEqual(configurations.StreamingEnabled, sentConfig.StreamingEnabled);
Expand Down Expand Up @@ -724,6 +728,11 @@ private static List<ImpressionCount> GetImpressionsCountsSentBackend(HttpClientM

return impressions;
}

private void sdkTimeout_callback(object sender, EventMetadata metadata)
{
SdkTimeout = true;
}
#endregion
}
}
36 changes: 25 additions & 11 deletions tests/Splitio.Integration-tests/StreamingClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ namespace Splitio.Integration_tests
public class StreamingClientTests
{
public static string EventSourcePath => "/eventsource";
private bool SdkReadyFlag = false;
private bool SdkReadyFlag2 = false;
private bool SdkUpdateFlag = false;
private EventMetadata eMetadata;
private bool SdkReady = false;
private bool SdkReady2 = false;
private bool SdkReady3 = false;
private bool SdkUpdate = false;

[TestMethod]
public void GetTreatment_SplitUpdate_ShouldFetch()
Expand Down Expand Up @@ -60,21 +60,27 @@ public void GetTreatment_SplitUpdate_ShouldFetch()
SegmentsRefreshRate = 3000,
AuthServiceURL = $"{url}/api/auth",
StreamingServiceURL = $"{url}{EventSourcePath}",
StreamingEnabled = true
StreamingEnabled = true,
Logger = SplitLogger.Console(Level.Debug)
};

var apikey = "apikey1";
var splitFactory = new SplitFactory(apikey, config);
var client = (SplitClient)splitFactory.Client();
client.SdkReady += sdkReady_callback;
client.SdkReady += sdkReady_callback2;
client.SdkUpdate += sdkUpdate_callback;

client.BlockUntilReady(10000);

var result = EvaluateWithDelay("admin", "push_test", "after_fetch", client);
client.SdkReady += sdkReady_callback3;

Assert.AreEqual("after_fetch", result);
Assert.IsTrue(SdkReadyFlag);
Assert.IsTrue(SdkReadyFlag2);
Assert.IsTrue(SdkReady);
Assert.IsTrue(SdkReady2);
Assert.IsTrue(SdkReady3);
Assert.IsTrue(SdkUpdate);

client.Destroy();
}
Expand Down Expand Up @@ -119,13 +125,11 @@ public void GetTreatment_SplitUpdate_ShouldNotFetch()

var splitFactory = new SplitFactory(apikey, config);
var client = splitFactory.Client();

client.BlockUntilReady(10000);

var result = EvaluateWithDelay("admin", "push_test", "on", client);

Assert.AreEqual("on", result);

client.Destroy();
}
}
Expand Down Expand Up @@ -774,12 +778,22 @@ public static string EvaluateWithDelay(string key, string splitName, string expe

private void sdkReady_callback(object sender, EventMetadata metadata)
{
SdkReadyFlag = true;
SdkReady = true;
}

private void sdkReady_callback2(object sender, EventMetadata metadata)
{
SdkReadyFlag2 = true;
SdkReady2 = true;
}

private void sdkReady_callback3(object sender, EventMetadata metadata)
{
SdkReady3 = true;
}

private void sdkUpdate_callback(object sender, EventMetadata metadata)
{
SdkUpdate = true;
}
}
}