Skip to content

Commit 855dc5b

Browse files
authored
Merge pull request #136 from Flagsmith/feat/local-evaluation-name
feat: Deprecate constructors with >1 parameter and IFlagsmithConfig interface. Add EnableLocalEvaluation and EnvironmentRefreshInterval properties
2 parents a28d729 + 1753943 commit 855dc5b

File tree

7 files changed

+1141
-254
lines changed

7 files changed

+1141
-254
lines changed

Flagsmith.Client.Test/FlagsmithTest.cs

Lines changed: 231 additions & 93 deletions
Large diffs are not rendered by default.

Flagsmith.Client.Test/FlagsmithTestDeprecated.cs

Lines changed: 668 additions & 0 deletions
Large diffs are not rendered by default.

Flagsmith.Client.Test/PollingManagerTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public void TestPollingManagerCallsUpdateEnvironmentOnStart()
1818
isCalled = true;
1919
return Task.CompletedTask;
2020
};
21-
var x = new PollingManager(callback);
21+
var x = new PollingManager(callback, TimeSpan.Zero);
2222
_ = x.StartPoll();
2323
Assert.True(isCalled);
2424
x.StopPoll();
@@ -32,7 +32,7 @@ public async Task TestPollingManagerCallsUpdateEnvironmentOnEachRefresh()
3232
calledCount += 1;
3333
return Task.CompletedTask;
3434
};
35-
var x = new PollingManager(callback, 1);
35+
var x = new PollingManager(callback, TimeSpan.FromSeconds(1));
3636
_ = x.StartPoll();
3737
await Task.Delay(3000);
3838
Assert.True(calledCount >= 3); // check pollingmanager polls atlease 3 times.

Flagsmith.FlagsmithClient/FlagsmithClient.cs

Lines changed: 118 additions & 129 deletions
Large diffs are not rendered by default.
Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,72 @@
11
using Microsoft.Extensions.Logging;
22
using System;
33
using System.Collections.Generic;
4+
using OfflineHandler;
5+
using System.Net.Http;
46

57
namespace Flagsmith
68
{
7-
public class FlagsmithConfiguration : IFlagsmithConfiguration
9+
public class FlagsmithConfiguration
810
{
9-
public FlagsmithConfiguration()
11+
private static readonly Uri DefaultApiUri = new Uri("https://edge.api.flagsmith.com/api/v1/");
12+
private TimeSpan _timeout;
13+
14+
/// <summary>
15+
/// <para>Override the URL of the Flagsmith API to communicate with.</para>
16+
/// <para>Deprecated since 7.1.0. Use <see cref="ApiUri"/> instead.</para>
17+
/// </summary>
18+
[Obsolete("Use ApiUri instead.")]
19+
public string ApiUrl
1020
{
11-
ApiUrl = "https://edge.api.flagsmith.com/api/v1/";
12-
EnvironmentKey = string.Empty;
13-
EnvironmentRefreshIntervalSeconds = 60;
21+
get => ApiUri.ToString();
22+
set => ApiUri = value.EndsWith("/") ? new Uri(value) : new Uri($"{value}/");
1423
}
24+
1525
/// <summary>
16-
/// Override the URL of the Flagsmith API to communicate with.
26+
/// Versioned base Flagsmith API URI to use for all requests. Defaults to
27+
/// <c>https://edge.api.flagsmith.com/api/v1/</c>.
28+
/// <example><code>new Uri("https://flagsmith.example.com/api/v1/")</code></example>
1729
/// </summary>
18-
public string ApiUrl { get; set; }
30+
public Uri ApiUri { get; set; } = DefaultApiUri;
31+
1932
/// <summary>
2033
/// The environment key obtained from Flagsmith interface.
2134
/// </summary>
2235
public string EnvironmentKey { get; set; }
36+
2337
/// <summary>
2438
/// Enables local evaluation of flags.
2539
/// </summary>
26-
public bool EnableClientSideEvaluation { get; set; }
40+
[Obsolete("Use EnableLocalEvaluation instead.")]
41+
public bool EnableClientSideEvaluation
42+
{
43+
get => EnableLocalEvaluation;
44+
set => EnableLocalEvaluation = value;
45+
}
46+
47+
/// <summary>
48+
/// Enables local evaluation of flags.
49+
/// </summary>
50+
public bool EnableLocalEvaluation { get; set; }
51+
52+
/// <summary>
53+
/// <para>If using local evaluation, specify the interval period between refreshes of local environment data.</para>
54+
/// <para>Deprecated since 7.1.0. Use <see cref="EnvironmentRefreshInterval"/> instead.</para>
55+
/// </summary>
56+
[Obsolete("Use EnvironmentRefreshInterval instead.")]
57+
public int EnvironmentRefreshIntervalSeconds
58+
{
59+
get => EnvironmentRefreshInterval.Seconds;
60+
set => EnvironmentRefreshInterval = TimeSpan.FromSeconds(value);
61+
}
2762
/// <summary>
2863
/// If using local evaluation, specify the interval period between refreshes of local environment data.
2964
/// </summary>
30-
public int EnvironmentRefreshIntervalSeconds { get; set; }
65+
public TimeSpan EnvironmentRefreshInterval { get; set; } = TimeSpan.FromSeconds(60);
3166
/// <summary>
3267
/// Callable which will be used in the case where flags cannot be retrieved from the API or a non existent feature is requested.
3368
/// </summary>
34-
public Func<string, Flag> DefaultFlagHandler { get; set; }
69+
public Func<string, Flag>? DefaultFlagHandler { get; set; }
3570
/// <summary>
3671
/// Provide logger for logging polling info & errors which is only applicable when client side evalution is enabled and analytics errors.
3772
/// </summary>
@@ -40,10 +75,24 @@ public FlagsmithConfiguration()
4075
/// if enabled, sends additional requests to the Flagsmith API to power flag analytics charts.
4176
/// </summary>
4277
public bool EnableAnalytics { get; set; }
78+
4379
/// <summary>
4480
/// Number of seconds to wait for a request to complete before terminating the request
4581
/// </summary>
46-
public Double? RequestTimeout { get; set; }
82+
public Double? RequestTimeout
83+
{
84+
get => _timeout.Seconds;
85+
set => _timeout = TimeSpan.FromSeconds(value ?? 100);
86+
}
87+
88+
/// <summary>
89+
/// Timeout duration to use for HTTP requests.
90+
/// </summary>
91+
public TimeSpan Timeout
92+
{
93+
get => _timeout;
94+
set => _timeout = value;
95+
}
4796
/// <summary>
4897
/// Total http retries for every failing request before throwing the final error.
4998
/// </summary>
@@ -56,11 +105,27 @@ public FlagsmithConfiguration()
56105
/// <summary>
57106
/// If enabled, the SDK will cache the flags for the duration specified in the CacheConfig
58107
/// </summary>
59-
public CacheConfig CacheConfig { get; set; }
108+
public CacheConfig CacheConfig { get; set; } = new CacheConfig(false);
109+
110+
/// <summary>
111+
/// Indicates whether the client is in offline mode.
112+
/// </summary>
113+
public bool OfflineMode { get; set; }
114+
115+
/// <summary>
116+
/// Handler for offline mode operations.
117+
/// </summary>
118+
public BaseOfflineHandler? OfflineHandler { get; set; }
119+
120+
/// <summary>
121+
/// Http client used for flagsmith-API requests.
122+
/// </summary>
123+
public HttpClient HttpClient { get; set; } = new HttpClient();
60124

125+
[Obsolete("This method will be removed in a future release.")]
61126
public bool IsValid()
62127
{
63-
return !string.IsNullOrEmpty(ApiUrl) && !string.IsNullOrEmpty(EnvironmentKey);
128+
return !string.IsNullOrEmpty(ApiUri.ToString()) && !string.IsNullOrEmpty(EnvironmentKey);
64129
}
65130
}
66131
}

Flagsmith.FlagsmithClient/IFlagsmithConfiguration.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
using System;
22
using System.Collections.Generic;
33
using Microsoft.Extensions.Logging;
4+
using OfflineHandler;
5+
using System.Net.Http;
46

57
namespace Flagsmith
68
{
9+
[Obsolete("Use FlagsmithConfiguration instead.")]
710
public interface IFlagsmithConfiguration
811
{
912
/// <summary>
@@ -61,6 +64,21 @@ public interface IFlagsmithConfiguration
6164
/// </summary>
6265
CacheConfig CacheConfig { get; set; }
6366

67+
/// <summary>
68+
/// Indicates whether the client is in offline mode.
69+
/// </summary>
70+
bool OfflineMode { get; set; }
71+
72+
/// <summary>
73+
/// Handler for offline mode operations.
74+
/// </summary>
75+
BaseOfflineHandler OfflineHandler { get; set; }
76+
77+
/// <summary>
78+
/// HTTP client used for Flagsmith API requests.
79+
/// </summary>
80+
HttpClient HttpClient { get; set; }
81+
6482
bool IsValid();
6583
}
66-
}
84+
}

Flagsmith.FlagsmithClient/PollingManager.cs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,27 @@ namespace Flagsmith
99
public class PollingManager : IPollingManager
1010
{
1111
private Timer _timer;
12-
private readonly CancellationTokenSource _CancellationTokenSource = new CancellationTokenSource();
13-
readonly Func<Task> _CallBack;
14-
readonly int _Interval;
12+
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
13+
private readonly Func<Task> _callback;
14+
private readonly TimeSpan _interval;
1515
/// <summary>
1616
///
1717
/// </summary>
18-
/// <param name="callBack">Awaitable function that will be polled.</param>
19-
/// <param name="intervalSeconds">Total delay in seconds between continous exection of callback.</param>
20-
public PollingManager(Func<Task> callBack, int intervalSeconds = 10)
18+
/// <param name="callback">Awaitable function that will be polled.</param>
19+
/// <param name="intervalSeconds">Total delay in seconds between continuous execution of callback.</param>
20+
[Obsolete("Use PollingManager(Func<Task>, TimeSpan) instead.")]
21+
public PollingManager(Func<Task> callback, int intervalSeconds = 10)
2122
{
22-
_CallBack = callBack;
23-
_Interval = intervalSeconds * 1000; //convert to milliseconds
23+
this._callback = callback;
24+
_interval = TimeSpan.FromSeconds(intervalSeconds);
25+
}
26+
27+
/// <param name="callback">Awaitable function that will be polled.</param>
28+
/// <param name="timespan">Polling interval.</param>
29+
public PollingManager(Func<Task> callback, TimeSpan timespan)
30+
{
31+
this._callback = callback;
32+
_interval = timespan;
2433
}
2534
/// <summary>
2635
/// Start calling callback continuously after provided interval
@@ -29,24 +38,24 @@ public PollingManager(Func<Task> callBack, int intervalSeconds = 10)
2938
public async Task StartPoll()
3039
{
3140
// Force a first call of the callback at least once and synchronously if it is awaited.
32-
await _CallBack.Invoke();
33-
_CancellationTokenSource.Token.ThrowIfCancellationRequested();
34-
_timer = new Timer(async (object state) =>
41+
await _callback.Invoke();
42+
_cancellationTokenSource.Token.ThrowIfCancellationRequested();
43+
_timer = new Timer(state =>
3544
{
36-
if (_CancellationTokenSource.Token.IsCancellationRequested)
45+
if (_cancellationTokenSource.Token.IsCancellationRequested)
3746
{
3847
_timer.Dispose();
3948
return;
4049
}
41-
await _CallBack.Invoke();
42-
}, null, _Interval, _Interval);
50+
_callback.Invoke().GetAwaiter().GetResult();
51+
}, null, _interval, _interval);
4352
}
4453
/// <summary>
45-
/// Stop continously exectuing callback
54+
/// Stop continuously executing callback
4655
/// </summary>
4756
public void StopPoll()
4857
{
49-
_CancellationTokenSource.Cancel();
58+
_cancellationTokenSource.Cancel();
5059
}
5160
}
5261
}

0 commit comments

Comments
 (0)