Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 184d088

Browse files
prepare 6.3.2 release (#152)
1 parent 8b22f5f commit 184d088

29 files changed

+1059
-1095
lines changed

src/LaunchDarkly.ServerSdk/FeatureFlagsState.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,29 +174,26 @@ public FeatureFlagsStateBuilder AddFlag(string flagKey, EvaluationDetail<LdValue
174174
result.Reason,
175175
0,
176176
false,
177+
false,
177178
null);
178179
}
179180

180181
// This method is defined with internal scope because metadata fields like trackEvents aren't
181182
// relevant to the main external use case for the builder (testing server-side code)
182183
internal FeatureFlagsStateBuilder AddFlag(string flagKey, LdValue value, int? variationIndex, EvaluationReason reason,
183-
int flagVersion, bool flagTrackEvents, UnixMillisecondTime? flagDebugEventsUntilDate)
184+
int flagVersion, bool flagTrackEvents, bool trackReason, UnixMillisecondTime? flagDebugEventsUntilDate)
184185
{
186+
bool flagIsTracked = flagTrackEvents || flagDebugEventsUntilDate != null;
185187
var flag = new FlagState
186188
{
187189
Value = value,
188190
Variation = variationIndex,
189-
DebugEventsUntilDate = flagDebugEventsUntilDate
191+
Version = (!_detailsOnlyIfTracked || flagIsTracked) ? flagVersion : (int?)null,
192+
Reason = trackReason || (_withReasons && (!_detailsOnlyIfTracked || flagIsTracked)) ? reason : (EvaluationReason?)null,
193+
DebugEventsUntilDate = flagDebugEventsUntilDate,
194+
TrackEvents = flagTrackEvents,
195+
TrackReason = trackReason
190196
};
191-
if (!_detailsOnlyIfTracked || flagTrackEvents || flagDebugEventsUntilDate != null)
192-
{
193-
flag.Version = flagVersion;
194-
flag.Reason = _withReasons ? reason : (EvaluationReason?)null;
195-
}
196-
if (flagTrackEvents)
197-
{
198-
flag.TrackEvents = true;
199-
}
200197
_flags[flagKey] = flag;
201198
return this;
202199
}
@@ -208,6 +205,7 @@ internal struct FlagState
208205
internal int? Variation { get; set; }
209206
internal int? Version { get; set; }
210207
internal bool TrackEvents { get; set; }
208+
internal bool TrackReason { get; set; }
211209
internal UnixMillisecondTime? DebugEventsUntilDate { get; set; }
212210
internal EvaluationReason? Reason { get; set; }
213211

@@ -218,6 +216,7 @@ public override bool Equals(object other)
218216
return Variation == o.Variation &&
219217
Version == o.Version &&
220218
TrackEvents == o.TrackEvents &&
219+
TrackReason == o.TrackReason &&
221220
DebugEventsUntilDate.Equals(o.DebugEventsUntilDate) &&
222221
Object.Equals(Reason, o.Reason);
223222
}
@@ -226,7 +225,8 @@ public override bool Equals(object other)
226225

227226
public override int GetHashCode()
228227
{
229-
return new HashCodeBuilder().With(Variation).With(Version).With(TrackEvents).With(DebugEventsUntilDate).With(Reason).Value;
228+
return new HashCodeBuilder().With(Variation).With(Version).With(TrackEvents).With(TrackReason).
229+
With(DebugEventsUntilDate).With(Reason).Value;
230230
}
231231
}
232232

@@ -255,9 +255,10 @@ public void WriteJson(object value, IValueWriter writer)
255255
{
256256
var flagMetadataObj = allMetadataObj.Name(entry.Key).Object();
257257
var meta = entry.Value;
258-
flagMetadataObj.Name("variation").IntOrNull(meta.Variation);
259-
flagMetadataObj.Name("version").IntOrNull(meta.Version);
258+
flagMetadataObj.MaybeName("variation", meta.Variation.HasValue).IntOrNull(meta.Variation);
259+
flagMetadataObj.MaybeName("version", meta.Version.HasValue).IntOrNull(meta.Version);
260260
flagMetadataObj.MaybeName("trackEvents", meta.TrackEvents).Bool(meta.TrackEvents);
261+
flagMetadataObj.MaybeName("trackReason", meta.TrackReason).Bool(meta.TrackReason);
261262
flagMetadataObj.MaybeName("debugEventsUntilDate", meta.DebugEventsUntilDate.HasValue)
262263
.Long(meta.DebugEventsUntilDate?.Value ?? 0);
263264
if (meta.Reason.HasValue)

src/LaunchDarkly.ServerSdk/Integrations/PollingDataSourceBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public IDataSource CreateDataSource(LdClientContext context, IDataSourceUpdates
110110

111111
context.Basic.Logger.Warn("You should only disable the streaming API if instructed to do so by LaunchDarkly support");
112112
FeatureRequestor requestor = new FeatureRequestor(context, configuredBaseUri);
113-
return new PollingProcessor(
113+
return new PollingDataSource(
114114
context,
115115
requestor,
116116
dataSourceUpdates,

src/LaunchDarkly.ServerSdk/Integrations/StreamingDataSourceBuilder.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public sealed class StreamingDataSourceBuilder : IDataSourceFactory, IDiagnostic
3939

4040
internal Uri _baseUri;
4141
internal TimeSpan _initialReconnectDelay = DefaultInitialReconnectDelay;
42-
internal StreamProcessor.EventSourceCreator _eventSourceCreator = null;
4342

4443
/// <summary>
4544
/// Deprecated method for setting a custom base URI for the streaming service.
@@ -95,24 +94,16 @@ public StreamingDataSourceBuilder InitialReconnectDelay(TimeSpan initialReconnec
9594
return this;
9695
}
9796

98-
// Exposed for testing
99-
internal StreamingDataSourceBuilder EventSourceCreator(StreamProcessor.EventSourceCreator eventSourceCreator)
100-
{
101-
_eventSourceCreator = eventSourceCreator;
102-
return this;
103-
}
104-
10597
/// <inheritdoc/>
10698
public IDataSource CreateDataSource(LdClientContext context, IDataSourceUpdates dataSourceUpdates)
10799
{
108100
var configuredBaseUri = _baseUri ??
109101
StandardEndpoints.SelectBaseUri(context.Basic.ServiceEndpoints, e => e.StreamingBaseUri, "Streaming", context.Basic.Logger);
110-
return new StreamProcessor(
102+
return new StreamingDataSource(
111103
context,
112104
dataSourceUpdates,
113105
configuredBaseUri,
114-
_initialReconnectDelay,
115-
_eventSourceCreator
106+
_initialReconnectDelay
116107
);
117108
}
118109

src/LaunchDarkly.ServerSdk/Internal/DataModelDependencies.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using LaunchDarkly.Sdk.Server.Internal.Model;
45

56
using static LaunchDarkly.Sdk.Server.Interfaces.DataStoreTypes;
67

78
namespace LaunchDarkly.Sdk.Server.Internal.DataSources
89
{
9-
internal struct KindAndKey
10+
internal readonly struct KindAndKey : IEquatable<KindAndKey>
1011
{
1112
public DataKind Kind { get; }
1213
public string Key { get; }
@@ -16,6 +17,16 @@ internal KindAndKey(DataKind kind, string key)
1617
Kind = kind;
1718
Key = key;
1819
}
20+
21+
public bool Equals(KindAndKey other)
22+
{
23+
return Kind == other.Kind && Key == other.Key;
24+
}
25+
26+
public override int GetHashCode()
27+
{
28+
return Kind.GetHashCode() * 17 + Key.GetHashCode();
29+
}
1930
}
2031

2132
internal class DependencyTracker

src/LaunchDarkly.ServerSdk/Internal/DataSources/DataSourceUpdatesImpl.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ public bool Init(FullDataSet<ItemDescriptor> allData)
118118
return false;
119119
}
120120

121+
// Calling Init implies that the data source is now in a valid state.
122+
UpdateStatus(DataSourceState.Valid, null);
123+
121124
// We must always update the dependency graph even if we don't currently have any event listeners, because if
122125
// listeners are added later, we don't want to have to reread the whole data store to compute the graph
123126
UpdateDependencyTrackerFromFullDataSet(allData);

src/LaunchDarkly.ServerSdk/Internal/DataSources/PollingProcessor.cs renamed to src/LaunchDarkly.ServerSdk/Internal/DataSources/PollingDataSource.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace LaunchDarkly.Sdk.Server.Internal.DataSources
1212
{
13-
internal sealed class PollingProcessor : IDataSource
13+
internal sealed class PollingDataSource : IDataSource
1414
{
1515
private readonly IFeatureRequestor _featureRequestor;
1616
private readonly IDataSourceUpdates _dataSourceUpdates;
@@ -21,7 +21,7 @@ internal sealed class PollingProcessor : IDataSource
2121
private readonly Logger _log;
2222
private CancellationTokenSource _canceller;
2323

24-
internal PollingProcessor(
24+
internal PollingDataSource(
2525
LdClientContext context,
2626
IFeatureRequestor featureRequestor,
2727
IDataSourceUpdates dataSourceUpdates,
@@ -67,10 +67,8 @@ private async Task UpdateTaskAsync()
6767
}
6868
else
6969
{
70-
if (_dataSourceUpdates.Init(allData.Value))
70+
if (_dataSourceUpdates.Init(allData.Value)) // this also automatically sets the state to Valid
7171
{
72-
_dataSourceUpdates.UpdateStatus(DataSourceState.Valid, null);
73-
7472
if (!_initialized.GetAndSet(true))
7573
{
7674
_initTask.SetResult(true);
@@ -117,8 +115,8 @@ private async Task UpdateTaskAsync()
117115
catch (Exception ex)
118116
{
119117
Exception realEx = (ex is AggregateException ae) ? ae.Flatten() : ex;
120-
LogHelpers.LogException(_log, "Polling for feature flag updates failed", realEx);
121-
118+
_log.Warn("Polling for feature flag updates failed: {0}", LogValues.ExceptionSummary(ex));
119+
_log.Debug(LogValues.ExceptionTrace(ex));
122120
_dataSourceUpdates.UpdateStatus(DataSourceState.Interrupted,
123121
DataSourceStatus.ErrorInfo.FromException(realEx));
124122
}

src/LaunchDarkly.ServerSdk/Internal/DataSources/StreamProcessor.cs renamed to src/LaunchDarkly.ServerSdk/Internal/DataSources/StreamingDataSource.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
namespace LaunchDarkly.Sdk.Server.Internal.DataSources
1818
{
19-
internal class StreamProcessor : IDataSource
19+
internal class StreamingDataSource : IDataSource
2020
{
2121
// The read timeout for the stream is not the same read timeout that can be set in the SDK configuration.
2222
// It is a fixed value that is set to be slightly longer than the expected interval between heartbeats
@@ -45,12 +45,11 @@ internal class StreamProcessor : IDataSource
4545
internal delegate IEventSource EventSourceCreator(Uri streamUri,
4646
HttpConfiguration httpConfig);
4747

48-
internal StreamProcessor(
48+
internal StreamingDataSource(
4949
LdClientContext context,
5050
IDataSourceUpdates dataSourceUpdates,
5151
Uri baseUri,
52-
TimeSpan initialReconnectDelay,
53-
EventSourceCreator eventSourceCreator
52+
TimeSpan initialReconnectDelay
5453
)
5554
{
5655
_log = context.Basic.Logger.SubLogger(LogNames.DataSourceSubLog);
@@ -69,7 +68,7 @@ EventSourceCreator eventSourceCreator
6968
_dataSourceUpdates.DataStoreStatusProvider.StatusChanged += OnDataStoreStatusChanged;
7069
}
7170

72-
_es = (eventSourceCreator ?? CreateEventSource)(_streamUri, _httpConfig);
71+
_es = CreateEventSource(_streamUri, _httpConfig);
7372
_es.MessageReceived += OnMessage;
7473
_es.Error += OnError;
7574
_es.Opened += OnOpen;
@@ -171,8 +170,15 @@ private void OnMessage(object sender, EventSource.MessageReceivedEventArgs e)
171170

172171
_es.Restart(false);
173172
}
174-
catch (StreamStoreException)
173+
catch (StreamStoreException ex)
175174
{
175+
var errorInfo = new DataSourceStatus.ErrorInfo
176+
{
177+
Kind = DataSourceStatus.ErrorKind.StoreError,
178+
Message = (ex.InnerException ?? ex).Message,
179+
Time = DateTime.Now
180+
};
181+
_dataSourceUpdates.UpdateStatus(DataSourceState.Interrupted, errorInfo);
176182
if (!_storeStatusMonitoringEnabled)
177183
{
178184
if (!_lastStoreUpdateFailed)
@@ -237,12 +243,11 @@ private void HandleMessage(string messageType, byte[] messageData)
237243
{
238244
case PUT:
239245
var putData = ParsePutData(messageData);
240-
if (!_dataSourceUpdates.Init(putData.Data))
246+
if (!_dataSourceUpdates.Init(putData.Data)) // this also automatically sets the state to Valid
241247
{
242248
throw new StreamStoreException("failed to write full data set to data store");
243249
}
244250
_lastStoreUpdateFailed = false;
245-
_dataSourceUpdates.UpdateStatus(DataSourceState.Valid, null);
246251
if (!_initialized.GetAndSet(true))
247252
{
248253
_initTask.TrySetResult(true);

src/LaunchDarkly.ServerSdk/Internal/Events/EventFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ FeatureFlag flagThatReferencesPrerequisite
9191
return e;
9292
}
9393

94-
private static bool IsExperiment(FeatureFlag flag, EvaluationReason? reason)
94+
internal static bool IsExperiment(FeatureFlag flag, EvaluationReason? reason)
9595
{
9696
if (!reason.HasValue)
9797
{

src/LaunchDarkly.ServerSdk/LaunchDarkly.ServerSdk.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@
3939

4040
<ItemGroup>
4141
<PackageReference Include="LaunchDarkly.Cache" Version="1.0.2" />
42-
<PackageReference Include="LaunchDarkly.CommonSdk" Version="5.4.0" />
42+
<PackageReference Include="LaunchDarkly.CommonSdk" Version="5.5.0" />
4343
<PackageReference Include="LaunchDarkly.EventSource" Version="4.1.3" />
44-
<PackageReference Include="LaunchDarkly.InternalSdk" Version="2.3.0" />
44+
<PackageReference Include="LaunchDarkly.InternalSdk" Version="2.3.2" />
4545
<PackageReference Include="LaunchDarkly.JsonStream" Version="1.0.3" />
4646
<PackageReference Include="LaunchDarkly.Logging" Version="1.0.1" />
4747
<PackageReference Include="System.Collections.Immutable" Version="1.7.1" />

src/LaunchDarkly.ServerSdk/LdClient.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,17 @@ public FeatureFlagsState AllFlagsState(User user, params FlagsStateOption[] opti
359359
try
360360
{
361361
Evaluator.EvalResult result = _evaluator.Evaluate(flag, user, EventFactory.Default);
362-
builder.AddFlag(flag.Key, result.Result.Value, result.Result.VariationIndex,
363-
result.Result.Reason, flag.Version, flag.TrackEvents, flag.DebugEventsUntilDate);
362+
bool inExperiment = EventFactory.IsExperiment(flag, result.Result.Reason);
363+
builder.AddFlag(
364+
flag.Key,
365+
result.Result.Value,
366+
result.Result.VariationIndex,
367+
result.Result.Reason,
368+
flag.Version,
369+
flag.TrackEvents || inExperiment,
370+
inExperiment,
371+
flag.DebugEventsUntilDate
372+
);
364373
}
365374
catch (Exception e)
366375
{

0 commit comments

Comments
 (0)