-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support for initialization, shutdown, and provider status e…
…vents. (#26) I will add configuration change event support in another PR.
- Loading branch information
1 parent
10a8992
commit fe8db98
Showing
11 changed files
with
417 additions
and
282 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/LaunchDarkly.OpenFeature.ServerProvider/LaunchDarklyProviderInitException.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System; | ||
|
||
namespace LaunchDarkly.OpenFeature.ServerProvider | ||
{ | ||
/// <summary> | ||
/// This exception is used to indicate that the provider has encountered a permanent exception, or has been | ||
/// shutdown, during initialization. | ||
/// </summary> | ||
public class LaunchDarklyProviderInitException: Exception | ||
{ | ||
/// <summary> | ||
/// Construct an exception with the given message. | ||
/// </summary> | ||
/// <param name="message">The exception message</param> | ||
public LaunchDarklyProviderInitException(string message) | ||
: base(message) | ||
{ | ||
} | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
src/LaunchDarkly.OpenFeature.ServerProvider/Provider.StatusProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using System.Threading.Channels; | ||
using System.Threading.Tasks; | ||
using LaunchDarkly.Logging; | ||
using OpenFeature.Constant; | ||
using OpenFeature.Model; | ||
|
||
namespace LaunchDarkly.OpenFeature.ServerProvider | ||
{ | ||
public sealed partial class Provider | ||
{ | ||
private class StatusProvider | ||
{ | ||
private ProviderStatus _providerStatus = ProviderStatus.NotReady; | ||
private object _statusLock = new object(); | ||
private Channel<object> _eventChannel; | ||
private string _providerName; | ||
private Logger _logger; | ||
|
||
public StatusProvider(Channel<object> eventChannel, string providerName, Logger logger) | ||
{ | ||
_eventChannel = eventChannel; | ||
_providerName = providerName; | ||
_logger = logger; | ||
} | ||
|
||
private void EmitProviderEvent(ProviderEventTypes type, string message) | ||
{ | ||
var payload = new ProviderEventPayload | ||
{ | ||
Type = type, | ||
ProviderName = _providerName | ||
}; | ||
if (message != null) | ||
{ | ||
payload.Message = message; | ||
} | ||
|
||
// Trigger the task do run, but don't wait for it. We wrap the exceptions inside SafeWrite, | ||
// so we aren't going to have unexpected exceptions here. | ||
Task.Run(() => SafeWrite(payload)).ConfigureAwait(false); | ||
} | ||
|
||
private async Task SafeWrite(ProviderEventPayload payload) | ||
{ | ||
try | ||
{ | ||
await _eventChannel.Writer.WriteAsync(payload).ConfigureAwait(false); | ||
} | ||
catch | ||
{ | ||
_logger.Warn("Failed to send provider status event"); | ||
} | ||
} | ||
|
||
public void SetStatus(ProviderStatus status, string message = null) | ||
{ | ||
lock (_statusLock) | ||
{ | ||
if (status == _providerStatus) | ||
{ | ||
return; | ||
} | ||
|
||
_providerStatus = status; | ||
switch (status) | ||
{ | ||
case ProviderStatus.NotReady: | ||
break; | ||
case ProviderStatus.Ready: | ||
EmitProviderEvent(ProviderEventTypes.ProviderReady, message); | ||
break; | ||
case ProviderStatus.Stale: | ||
EmitProviderEvent(ProviderEventTypes.ProviderStale, message); | ||
break; | ||
case ProviderStatus.Error: | ||
default: | ||
EmitProviderEvent(ProviderEventTypes.ProviderError, message); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
public ProviderStatus Status | ||
{ | ||
get | ||
{ | ||
lock (_statusLock) | ||
{ | ||
return _providerStatus; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.