Skip to content

Commit

Permalink
feat: Add support for configuration changed event.
Browse files Browse the repository at this point in the history
Remove handler on shutdown.

Async send provider events.

Fix events.
  • Loading branch information
kinyoklion committed Feb 23, 2024
1 parent fe8db98 commit 5c56ea0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ private async Task SafeWrite(ProviderEventPayload payload)
{
await _eventChannel.Writer.WriteAsync(payload).ConfigureAwait(false);
}
catch
catch(System.Exception e)
{
_logger.Warn("Failed to send provider status event");
_logger.Warn($"Failed to send provider status event: {e.Message}");
}
}

Expand Down
36 changes: 33 additions & 3 deletions src/LaunchDarkly.OpenFeature.ServerProvider/Provider.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LaunchDarkly.Logging;
using LaunchDarkly.Sdk;
using LaunchDarkly.Sdk.Internal.Concurrent;
using LaunchDarkly.Sdk.Server;
Expand Down Expand Up @@ -28,19 +30,22 @@ public sealed partial class Provider : FeatureProvider
private readonly ILdClient _client;
private readonly EvalContextConverter _contextConverter;
private readonly StatusProvider _statusProvider;

private readonly AtomicBoolean _initializeCalled = new AtomicBoolean(false);

// There is no support for void task completion, so we use bool as a dummy result type.
private readonly TaskCompletionSource<bool> _initCompletion = new TaskCompletionSource<bool>();
private readonly Logger _logger;

private const string ProviderShutdownMessage =
"the provider has encountered a permanent error or been shutdown";

internal Provider(ILdClient client)
{
_client = client;
var logger = _client.GetLogger().SubLogger(NameSpace);
_statusProvider = new StatusProvider(EventChannel, _metadata.Name, logger);
_contextConverter = new EvalContextConverter(logger);
_logger = _client.GetLogger().SubLogger(NameSpace);
_statusProvider = new StatusProvider(EventChannel, _metadata.Name, _logger);
_contextConverter = new EvalContextConverter(_logger);
}

/// <summary>
Expand Down Expand Up @@ -127,6 +132,8 @@ public override Task Initialize(EvaluationContext context)
return _initCompletion.Task;
}

_client.FlagTracker.FlagChanged += FlagChangeHandler;

_client.DataSourceStatusProvider.StatusChanged += StatusChangeHandler;

// We start listening for status changes and then we check the current status change. If we do not check
Expand All @@ -152,13 +159,36 @@ public override Task Initialize(EvaluationContext context)
public override Task Shutdown()
{
_client.DataSourceStatusProvider.StatusChanged -= StatusChangeHandler;
_client.FlagTracker.FlagChanged -= FlagChangeHandler;
(_client as IDisposable)?.Dispose();
_statusProvider.SetStatus(ProviderStatus.NotReady);
return Task.CompletedTask;
}

#endregion

private void FlagChangeHandler(object sender, FlagChangeEvent changeEvent)
{
Task.Run(() => SafeWriteChangeEvent(changeEvent)).ConfigureAwait(false);
}

private async Task SafeWriteChangeEvent(FlagChangeEvent changeEvent)
{
try
{
await EventChannel.Writer.WriteAsync(new ProviderEventPayload
{
ProviderName = _metadata.Name,
Type = ProviderEventTypes.ProviderConfigurationChanged,
FlagsChanged = new List<string>{changeEvent.Key},
}).ConfigureAwait(false);
}
catch(Exception e)
{
_logger.Warn($"Encountered an error sending configuration changed events: {e.Message}");
}
}

private void StatusChangeHandler(object sender, DataSourceStatus status)
{
switch (status.State)
Expand Down

0 comments on commit 5c56ea0

Please sign in to comment.