Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
(#5) scoped configuration & public interface for events (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
eli-darkly authored Sep 7, 2021
1 parent cf38a01 commit c919883
Show file tree
Hide file tree
Showing 25 changed files with 878 additions and 352 deletions.
51 changes: 48 additions & 3 deletions src/LaunchDarkly.ClientSdk/Components.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using LaunchDarkly.Logging;
using LaunchDarkly.Sdk.Client.Integrations;
using LaunchDarkly.Sdk.Client.Interfaces;
using LaunchDarkly.Sdk.Client.Internal;

namespace LaunchDarkly.Sdk.Client
{
Expand Down Expand Up @@ -88,6 +89,24 @@ public static LoggingConfigurationBuilder Logging() =>
public static LoggingConfigurationBuilder Logging(ILogAdapter adapter) =>
new LoggingConfigurationBuilder().Adapter(adapter);

/// <summary>
/// Returns a configuration object that disables analytics events.
/// </summary>
/// <remarks>
/// Passing this to <see cref="ConfigurationBuilder.Events(IEventProcessorFactory)"/> causes
/// the SDK to discard all analytics events and not send them to LaunchDarkly, regardless of
/// any other configuration.
/// </remarks>
/// <example>
/// <code>
/// var config = Configuration.Builder(mobileKey)
/// .Events(Components.NoEvents)
/// .Build();
/// </code>
/// </example>
public static IEventProcessorFactory NoEvents =>
ComponentsImpl.NullEventProcessorFactory.Instance;

/// <summary>
/// A configuration object that disables logging.
/// </summary>
Expand All @@ -96,7 +115,7 @@ public static LoggingConfigurationBuilder Logging(ILogAdapter adapter) =>
/// </remarks>
/// <example>
/// <code>
/// var config = Configuration.Builder(sdkKey)
/// var config = Configuration.Builder(mobileKey)
/// .Logging(Components.NoLogging)
/// .Build();
/// </code>
Expand Down Expand Up @@ -131,7 +150,7 @@ public static LoggingConfigurationBuilder Logging(ILogAdapter adapter) =>
/// </remarks>
/// <example>
/// <code>
/// var config = Configuration.Builder(sdkKey)
/// var config = Configuration.Builder(mobileKey)
/// .DataSource(Components.PollingDataSource()
/// .PollInterval(TimeSpan.FromSeconds(45)))
/// .Build();
Expand All @@ -143,6 +162,32 @@ public static LoggingConfigurationBuilder Logging(ILogAdapter adapter) =>
public static PollingDataSourceBuilder PollingDataSource() =>
new PollingDataSourceBuilder();

/// <summary>
/// Returns a configuration builder for analytics event delivery.
/// </summary>
/// <remarks>
/// <para>
/// The default configuration has events enabled with default settings. If you want to
/// customize this behavior, call this method to obtain a builder, change its properties
/// with the <see cref="EventProcessorBuilder"/> methods, and pass it to
/// <see cref="ConfigurationBuilder.Events(IEventProcessorFactory)"/>.
/// </para>
/// <para>
/// To completely disable sending analytics events, use <see cref="NoEvents"/> instead.
/// </para>
/// </remarks>
/// <example>
/// <code>
/// var config = Configuration.Builder(mobileKey)
/// .Events(Components.SendEvents()
/// .Capacity(5000)
/// .FlushInterval(TimeSpan.FromSeconds(2)))
/// .Build();
/// </code>
/// </example>
/// <returns>a builder for setting event properties</returns>
public static EventProcessorBuilder SendEvents() => new EventProcessorBuilder();

/// <summary>
/// Returns a configurable factory for using streaming mode to get feature flag data.
/// </summary>
Expand All @@ -165,7 +210,7 @@ public static PollingDataSourceBuilder PollingDataSource() =>
/// </remarks>
/// <example>
/// <code>
/// var config = Configuration.Builder(sdkKey)
/// var config = Configuration.Builder(mobileKey)
/// .DataSource(Components.StreamingDataSource()
/// .InitialReconnectDelay(TimeSpan.FromMilliseconds(500)))
/// .Build();
Expand Down
67 changes: 4 additions & 63 deletions src/LaunchDarkly.ClientSdk/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,10 @@ public sealed class Configuration
internal IBackgroundModeManager BackgroundModeManager { get; }
internal IConnectivityStateManager ConnectivityStateManager { get; }
internal IDeviceInfo DeviceInfo { get; }
internal IEventProcessor EventProcessor { get; }
internal IFlagCacheManager FlagCacheManager { get; }
internal IFlagChangedEventManager FlagChangedEventManager { get; }
internal IPersistentStorage PersistentStorage { get; }

/// <summary>
/// Whether or not user attributes (other than the key) should be private (not sent to
/// the LaunchDarkly server).
/// </summary>
/// <remarks>
/// By default, this is <see langword="false"/>. If <see langword="true"/>, all of the user attributes
/// will be private, not just the attributes specified with <see cref="ConfigurationBuilder.PrivateAttribute(UserAttribute)"/>
/// or with the <see cref="IUserBuilderCanMakeAttributePrivate.AsPrivateAttribute"/> method.
/// </remarks>
public bool AllAttributesPrivate { get; }

/// <summary>
/// Whether to disable the automatic sending of an alias event when the current user is changed
/// to a non-anonymous user and the previous user was anonymous.
Expand Down Expand Up @@ -97,43 +85,18 @@ public sealed class Configuration
/// </remarks>
public bool EvaluationReasons { get; }

/// <summary>
/// The capacity of the event buffer.
/// </summary>
/// <remarks>
/// The client buffers up to this many events in memory before flushing. If the capacity is exceeded
/// before the buffer is flushed, events will be discarded. Increasing the capacity means that events
/// are less likely to be discarded, at the cost of consuming more memory.
/// </remarks>
public int EventCapacity { get; }

/// <summary>
/// The time between flushes of the event buffer.
/// </summary>
/// <remarks>
/// Decreasing the flush interval means that the event buffer is less likely to reach capacity.
/// </remarks>
public TimeSpan EventFlushInterval { get; }

/// <summary>
/// The base URL of the LaunchDarkly analytics event server.
/// A factory object that creates an implementation of <see cref="IEventProcessor"/>, responsible
/// for sending analytics events.
/// </summary>
public Uri EventsUri { get; }
public IEventProcessorFactory EventProcessorFactory { get; }

/// <summary>
/// The object to be used for sending HTTP requests, if a specific implementation is desired.
/// </summary>
public HttpMessageHandler HttpMessageHandler { get; }

/// <summary>
/// Sets whether to include full user details in every analytics event.
/// </summary>
/// <remarks>
/// The default is <see langword="false"/>: events will only include the user key, except for one
/// "index" event that provides the full details for the user.
/// </remarks>
public bool InlineUsersInEvents { get; }

internal ILoggingConfigurationFactory LoggingConfigurationFactory { get; }

/// <summary>
Expand All @@ -158,16 +121,6 @@ public sealed class Configuration
/// </remarks>
public bool PersistFlagValues { get; }

/// <summary>
/// Attribute names that have been marked as private for all users.
/// </summary>
/// <remarks>
/// Any users sent to LaunchDarkly with this configuration active will have attributes with this name
/// removed, even if you did not use the <see cref="IUserBuilderCanMakeAttributePrivate.AsPrivateAttribute"/>
/// method when building the user.
/// </remarks>
public IImmutableSet<UserAttribute> PrivateAttributeNames { get; }

/// <summary>
/// The timeout when reading data from the streaming connection.
/// </summary>
Expand All @@ -184,11 +137,6 @@ public sealed class Configuration
internal bool UseReport { get; }
// UseReport is currently disabled due to Android HTTP issues (ch47341), but it's still implemented internally

internal static readonly Uri DefaultUri = new Uri("https://app.launchdarkly.com");
internal static readonly Uri DefaultStreamUri = new Uri("https://clientstream.launchdarkly.com");
internal static readonly Uri DefaultEventsUri = new Uri("https://mobile.launchdarkly.com");
internal static readonly int DefaultEventCapacity = 100;
internal static readonly TimeSpan DefaultEventFlushInterval = TimeSpan.FromSeconds(5);
internal static readonly TimeSpan DefaultReadTimeout = TimeSpan.FromMinutes(5);
internal static readonly TimeSpan DefaultReconnectTime = TimeSpan.FromSeconds(1);
internal static readonly TimeSpan DefaultConnectionTimeout = TimeSpan.FromSeconds(10);
Expand Down Expand Up @@ -243,31 +191,24 @@ public static ConfigurationBuilder Builder(Configuration fromConfiguration)

internal Configuration(ConfigurationBuilder builder)
{
AllAttributesPrivate = builder._allAttributesPrivate;
AutoAliasingOptOut = builder._autoAliasingOptOut;
ConnectionTimeout = builder._connectionTimeout;
DataSourceFactory = builder._dataSourceFactory;
EnableBackgroundUpdating = builder._enableBackgroundUpdating;
EvaluationReasons = builder._evaluationReasons;
EventFlushInterval = builder._eventFlushInterval;
EventCapacity = builder._eventCapacity;
EventsUri = builder._eventsUri;
EventProcessorFactory = builder._eventProcessorFactory;
HttpMessageHandler = object.ReferenceEquals(builder._httpMessageHandler, ConfigurationBuilder.DefaultHttpMessageHandlerInstance) ?
PlatformSpecific.Http.CreateHttpMessageHandler(builder._connectionTimeout, builder._readTimeout) :
builder._httpMessageHandler;
InlineUsersInEvents = builder._inlineUsersInEvents;
LoggingConfigurationFactory = builder._loggingConfigurationFactory;
MobileKey = builder._mobileKey;
Offline = builder._offline;
PersistFlagValues = builder._persistFlagValues;
PrivateAttributeNames = builder._privateAttributeNames is null ? null :
builder._privateAttributeNames.ToImmutableHashSet();
UseReport = builder._useReport;

BackgroundModeManager = builder._backgroundModeManager;
ConnectivityStateManager = builder._connectivityStateManager;
DeviceInfo = builder._deviceInfo;
EventProcessor = builder._eventProcessor;
FlagCacheManager = builder._flagCacheManager;
FlagChangedEventManager = builder._flagChangedEventManager;
PersistentStorage = builder._persistentStorage;
Expand Down
Loading

0 comments on commit c919883

Please sign in to comment.