Skip to content

Releases: launchdarkly/dotnet-server-sdk

5.14.1

04 Mar 02:27
Compare
Choose a tag to compare

[5.14.1] - 2021-03-03

Fixed:

  • The long-running task that the SDK uses to process analytics events was being created in a way that could unnecessarily reduce availability of the managed thread pool, potentially causing unexpected delays in asynchronous task scheduling elsewhere in an application.

6.0.0-beta.1

23 Feb 00:03
Compare
Choose a tag to compare
6.0.0-beta.1 Pre-release
Pre-release

[6.0.0-beta.1] - 2021-02-22

This is the first beta release of the 6.0 SDK-- a major rewrite that introduces a cleaner API design, adds new features, and makes the SDK code easier to maintain and extend. See the .NET 5.x to 6.0 migration guide for an in-depth look at the changes in 6.0; the following is a summary.

Added:

  • You can tell the SDK to notify you whenever a feature flag's configuration has changed (either in general, or in terms of its result for a specific user), using LDClient.FlagTracker.
  • You can monitor the status of the SDK's data source (which normally means the streaming connection to the LaunchDarkly service) with LdClient.DataSourceStatusProvider. This allows you to check the current connection status, and to be notified if this status changes.
  • You can monitor the status of a persistent data store with LDClient.DataStoreStatusProvider. This allows you to check whether database updates are succeeding, or to be notified if this status changes.
  • HttpConfigurationBuilder.Proxy allows you to specify an HTTP/HTTPS proxy server programmatically, rather than using .NET's HTTPS_PROXY environment variable. That was already possibly to do by specifying an HttpClientHandler that had a proxy; this is a shortcut for the same thing.
  • HttpConfigurationBuilder.CustomHeader allows you to specify custom HTTP headers that should be added to every HTTP/HTTPS request made by the SDK.
  • There is now a DoubleVariation method for getting a numeric flag value as the double type (as opposed to FloatVariation which returns a float).
  • The Alias method of LdClient is a new LaunchDarkly feature for associating two user keys with each other in analytics data.
  • The TestData class in LaunchDarkly.Sdk.Server.Integrations is a new way to inject feature flag data programmatically into the SDK for testing—either with fixed values for each flag, or with targets and/or rules that can return different values for different users. Unlike FileData, this mechanism does not use any external resources, only the data that your test code has provided.
  • ConfigurationBuilder.Logging is a new configuration category for options related to logging. This includes a new mechanism for specifying where log output should be sent, instead of using the Common.Logging framework to configure this.
  • LoggingConfigurationBuilder.LogDataSourceOutageAsErrorAfter controls the new connection failure logging behavior described below under "behavioral changes".
  • The LaunchDarkly.Sdk.Json namespace provides methods for converting types like User and FeatureFlagsState to and from JSON.
  • The LaunchDarkly.Sdk.UserAttribute type provides a less error-prone way to refer to user attribute names in configuration, and can also be used to get an arbitrary attribute from a user.
  • The LaunchDarkly.Sdk.UnixMillisecondTime type provides convenience methods for converting to and from the Unix epoch millisecond time format that LaunchDarkly uses for all timestamp values.

Changed (requirements/dependencies/build):

  • The SDK's build targets are now .NET Standard 2.0 and .NET Framework 4.5.2. This means it can be used in applications that run on .NET Core 2.1 and above, .NET Framework 4.5.2 and above, .NET 5.0 and above, or in a portable library that is targeted to .NET Standard 2.0 and above.
  • The SDK no longer has a dependency on Common.Logging. Instead, it uses a similar but simpler logging facade, the LaunchDarkly.Logging package, which has adapters for various logging destinations.
  • The SDK no longer has a dependency on Newtonsoft.Json. It uses the System.Text.Json API internally on platforms where that is available; on others, such as .NET Framework 4.5.x, it uses a lightweight custom implementation. This removes the potential for dependency version conflicts in applications that use Newtonsoft.Json for their own purposes. Converting data types like User and LdValue to and from JSON with System.Text.Json will always work; converting them with Newtonsoft.Json requires an extra package, LaunchDarkly.CommonSdk.JsonNet.
  • The SDK's dependencies for its own implementation details are now LaunchDarkly.CommonSdk, LaunchDarkly.EventSource, LaunchDarkly.InternalSdk, and LaunchDarkly.JsonStream. You should not need to reference these assemblies directly, as they are loaded automatically when you install the main NuGet package LaunchDarkly.ServerSdk. Previously there was also a variant called LaunchDarkly.CommonSdk.StrongName that was used by the release build of the SDK, but that has been removed.

Changed (API changes):

  • The base namespace has changed: types that were previously in LaunchDarkly.Client are now in either LaunchDarkly.Sdk or LaunchDarkly.Sdk.Server. The LaunchDarkly.Sdk namespace contains types that are not specific to the server-side .NET SDK (that is, they will also be used by the Xamarin SDK): EvaluationDetail, LdValue, User, and UserBuilder. Types that are specific to the server-side .NET SDK, such as Configuration and LdClient, are in LaunchDarkly.Sdk.Server`.
  • Many properties have been moved out of ConfigurationBuilder, into sub-builders that are specific to one are of functionality (such as streaming, or analytics events). See ConfigurationBuilder and Components.
  • User and Configuration objects are now immutable. To specify properties for these classes, you must now use User.Builder and Configuration.Builder.
  • The following things now use the type LdValue instead of JToken: custom attribute values in User.Custom; JSON flag variations returned by JsonVariation, JsonVariationDetail, and AllFlags; the optional data parameter of LdClient.Track.
  • EvaluationReason is now a single struct type rather than a base class.
  • LaunchDarkly.Client.Files.FileComponents has been moved to LaunchDarkly.Sdk.Server.Integrations.FileData.
  • LdClient.Initialized is now a read-only property rather than a method.
  • Interfaces for creating custom components, such as IFeatureStore, now have a new namespace (LaunchDarkly.Sdk.Server.Interfaces), new names, and somewhat different semantics due to changes in the SDK's internal architecture. Any existing custom component implementations will need to be revised to work with .NET SDK 5.x.
  • The ILdClient interface is now in LaunchDarkly.Sdk.Server.Interfaces instead of the main namespace.
  • The IConfigurationBuilder interface has been replaced by the concrete class ConfigurationBuilder.

Changed (behavioral changes):

  • In streaming mode, the SDK will now drop and restart the stream connection if either 1. it receives malformed data (indicating that some data may have been lost before reaching the application) or 2. you are using a database integration (a persistent data store) and a database error happens while trying to store the received data. In both cases, the intention is to make sure updates from LaunchDarkly are not lost; restarting the connection causes LaunchDarkly to re-send the entire flag data set. This makes the .NET SDK's behavior consistent with other LaunchDarkly server-side SDKs.
  • However, if you have set the caching behavior to "cache forever" (see PersistentDataStoreConfiguration), the stream will not restart after a database error; instead, all updates will still be accumulated in the cache, and will be written to the database automatically if the database becomes available again.
  • Logging now uses a simpler, more stable set of logger names instead of using the names of specific implementation classes that are subject to change. General messages are logged under LaunchDarkly.Sdk.Server.LdClient, while messages about specific areas of functionality are logged under that name plus .DataSource (streaming, polling, file data, etc.), .DataStore (database integrations), .Evaluation (unexpected errors during flag evaluations), or .Events (analytics event processing).
  • Network failures and server errors for streaming or polling requests were previously logged at Error level in most cases but sometimes at Warn level. They are now all at Warn level, but with a new behavior: if connection failures continue without a successful retry for a certain amount of time, the SDK will log a special Error-level message to warn you that this is not just a brief outage. The amount of time is one minute by default, but can be changed with the new LogDataSourceOutageAsErrorAfter option in LoggingConfigurationBuilder.
  • Many internal methods have been rewritten to reduce the number of heap allocations in general.
  • Evaluation of rules involving regex matches, date/time values, and semantic versions, has been speeded up by pre-parsing the values in the rules.
  • Evaluation of rules involving an equality match to multiple values (such as "name is one of X, Y, Z") has been speeded up by converting the list of values to a set.
  • If analytics events are disabled with Components.NoEvents, the SDK now avoids generating any analytics event objects internally. Previously they were created and then discarded, causing unnecessary heap churn.
  • When accessing a floating-point flag value with IntVariation, it will now truncate (round toward zero) rather than rounding to the nearest integer. This is consistent with normal C# behavior and with most other LaunchDarkly SDKs.

Fixed:

  • If an unexpected exception occurred while evaluating one clause in a flag rule, the SDK was simply ignoring the clause. For consistency with the other SDKs, it now treats this as a failed evaluation.

Removed:

  • All types and methods that were deprecated as of the last .NET SDK 5.x re...
Read more

5.14.0

27 Jan 00:38
Compare
Choose a tag to compare

[5.14.0] - 2021-01-26

The purpose of this release is to introduce newer APIs for configuring the SDK, corresponding to how configuration will work in the upcoming 6.0 release. These are very similar to the configuration APIs in the recent 5.x releases of the LaunchDarkly server-side Java and Go SDKs.

The corresponding older APIs are now deprecated. If you update to this release, you will see deprecation warnings where you have used them, but they will still work. This should make it easier to migrate your code to the newer APIs, in order to be ready to update to the 6.0 release in the future without drastic changes. For details, see below, and also see the API documentation for IConfigurationBuilder.

Other than the configuration methods, there are no changes to SDK functionality in this release.

Added:

  • Previously, most configuration options were set by setter methods in IConfigurationBuilder. These are being superseded by builders that are specific to one area of functionality: for instance, Components.StreamingDataSource() and Components.PollingDataSource() provide builders/factories that have options specific to streaming or polling, the SDK's many options related to analytics events are now in a builder returned by Components.SendEvents(), and HTTP-related options such as ConnectTimeout are now in a builder returned by Components.HttpConfiguration(). Using this newer API makes it clearer which options are for what, and makes it impossible to write contradictory configurations like .IsStreamingEnabled(false).StreamUri(someUri).
  • There is a new API for specifying a persistent data store (usually a database integration). This is now done using the new method Components.PersistentDataStore and one of the new integration factories in the namespace Launchdarkly.Client.Integrations. The next releases of the integration packages for Redis, Consul, and DynamoDB will use these semantics.

Changed:

  • The components "feature store" and "update processor" are being renamed to "data store" and "data source". The interfaces for these are still called IFeatureStore and IUpdateProcessor for backward compatibility, but the newer configuration methods use the new names. The interfaces will be renamed in the next major version.
  • In the newer API, the mode formerly named "LDD" (LaunchDarkly daemon), where the SDK reads feature flags from a database that is populated by the LaunchDarkly Relay Proxy or some other process, has been renamed to ExternalUpdatesOnly. It is now an option for the DataSource configuration method.

Deprecated:

  • In IConfigurationBuilder: all methods for setting individual properties related to streaming, polling, events, and HTTP configuration; also, the UseLdd option (see above).
  • In Components: DefaultEventProcessor, DefaultUpdateProcessor, InMemoryFeatureStore, NullEventProcessor, NullUpdateProcessor. Replacements for these are described in the API documentation.

5.13.1

06 Nov 02:17
Compare
Choose a tag to compare

[5.13.1] - 2020-11-05

Changed:

  • Updated the LaunchDarkly.EventSource dependency to a version that has a specific target for .NET Standard 2.0. Previously, that package targeted only .NET Standard 1.4 and .NET Framework 4.5. There is no functional difference between these targets, but .NET Core application developers may wish to avoid linking to any .NET Standard 1.x assemblies on general principle.

5.13.0

11 Feb 00:58
Compare
Choose a tag to compare

[5.13.0] - 2020-02-10

Note: if you are using the LaunchDarkly Relay Proxy to forward events, update the Relay to version 5.10.0 or later before updating to this .NET SDK version.

Added:

  • The SDK now periodically sends diagnostic data to LaunchDarkly, describing the version and configuration of the SDK, the architecture and version of the runtime platform, and performance statistics. No credentials, hostnames, or other identifiable values are included. This behavior can be disabled with IConfigurationBuilder.DiagnosticOptOut or configured with IConfigurationBuilder.DiagnosticRecordingInterval.
  • With the file data source, it is now possible to customize the logic for reading a file in case there are special OS considerations. (Thanks, JeffAshton!)

Fixed:

  • The SDK now specifies a uniquely identifiable request header when sending events to LaunchDarkly to ensure that events are only processed once, even if the SDK sends them two times due to a failed initial attempt.

5.12.0

06 Jan 23:58
Compare
Choose a tag to compare

[5.12.0] - 2020-01-06

Added:

  • IUserBuilder.Secondary is a new name for SecondaryKey (for consistency with other SDKs), and allows you to make the secondary attribute private.
  • User.Secondary (same as SecondaryKey).
  • FeatureFlagsState now has a Builder method for constructing a new instance (useful in testing). (#125)

Deprecated:

  • IUserBuilder.SecondaryKey, User.SecondaryKey.

5.11.0

13 Dec 22:08
Compare
Choose a tag to compare

[5.11.0] - 2019-12-13

Added:

  • With FileDataSourceFactory, it is now possible to specify that duplicate flag keys in data files should be ignored rather than causing an error; in this mode, it will use only the first occurrence of each flag key. This allows, for instance, implementing rolling updates of flag data by putting the newest data in a file that is specified first in your file list. (Thanks, JeffAshton!)

Fixed:

  • In rare circumstances (depending on the exact data in the flag configuration, the flag's salt value, and the user properties), a percentage rollout could fail and return a default value, logging the error "Data inconsistency in feature flag ... variation/rollout object with no variation or rollout". This would happen if the user's hashed value fell exactly at the end of the last "bucket" (the last variation defined in the rollout). This has been fixed so that the user will get the last variation.

5.10.0

12 Nov 22:28
Compare
Choose a tag to compare

[5.10.0] - 2019-11-12

Added:

  • Added ILdClient extension methods EnumVariation and EnumVariationDetail, which convert strings to enums.
  • Added LaunchDarkly.Logging.ConsoleAdapter as a convenience for quickly enabling console logging; this is equivalent to Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, but the latter is not available on some platforms.
  • LdValue helpers for dealing with array/object values, without having to use an intermediate List or Dictionary: BuildArray, BuildObject, Count, Get.
  • LdValue.Parse(). It is also possible to use Newtonsoft.Json.JsonConvert to parse or serialize LdValue, but since the implementation may change in the future, using the type's own methods is preferable.

Changed:

  • EvaluationReason properties all exist on the base class now, so for instance you do not need to cast to RuleMatch to get the RuleId property. This is in preparation for a future API change in which EvaluationReason will become a struct instead of a base class.

Fixed:

  • Improved memory usage and performance when processing analytics events: the SDK now encodes event data to JSON directly, instead of creating intermediate objects and serializing them via reflection.
  • LdValue.Equals() incorrectly returned true for object (dictionary) values that were not equal.

Deprecated:

  • EvaluationReason subclasses. Use only the base class properties and methods to ensure compatibility with future versions.

5.9.0

08 Oct 00:29
9f17034
Compare
Choose a tag to compare

[5.9.0] - 2019-10-07

Added:

  • IUserBuilder.AnonymousOptional allows setting the Anonymous property to null (necessary for consistency with other SDKs). See note about this under Fixed.
  • FileDataSourceBuilder.WithSkipMissingPaths allows suppressing file-not-found errors in FileDataSource, if you have a test setup that may add or remove data files dynamically. (Thanks, JeffAshton!)

Changed:

  • It is now possible to specify an infinite cache TTL for persistent feature stores by setting the TTL to a negative number, in which case the persistent store will never be read unless the application restarts. Use this mode with caution as described in the comment for FeatureStoreCacheConfig.Ttl.
  • Improved the performance of InMemoryFeatureStore by using an ImmutableDictionary that is replaced under a lock whenever there is an update, so reads do not need a lock. (Thanks, JeffAshton!)
  • The SDK now has a dependency on System.Collections.Immutable. It refers to version 1.2.0 because the SDK does not use any APIs that were added or changed after that point, but if you want to use that package yourself it is best to declare your own dependency rather than relying on this transitive dependency, since there may have been fixes or improvements in other APIs.

Fixed:

  • IUserBuilder was incorrectly setting the user's Anonymous property to null even if it had been explicitly set to false. Null and false behave the same in terms of LaunchDarkly's user indexing behavior, but currently it is possible to create a feature flag rule that treats them differently. So IUserBuilder.Anonymous(false) now correctly sets it to false, just as the deprecated method UserExtensions.WithAnonymous(false) would.
  • LdValue.Convert.Long was mistakenly converting to an int rather than a long. (CommonSdk #32)
  • FileDataSource could fail to read a file if it noticed the file being modified by another process before the other process had finished writing it. This fix only affects Windows, since in Windows it is not possible to replace a file's contents atomically; in a Unix-like OS, the preferred approach is to create a temporary file and rename it to replace the original file. (Thanks, JeffAshton!)

5.8.0

01 Oct 22:57
d9459ae
Compare
Choose a tag to compare

[5.8.0] - 2019-10-01

Added:

  • Added support for upcoming LaunchDarkly experimentation features. See ILdClient.Track(string, User, LdValue, double).

Fixed:

  • Fixed a bug due to incorrect use of a lock that could cause a read from InMemoryFeatureStore to fail if done at the same time as an update. (Thanks, JeffAshton!)