-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathFeatureProvider.cs
144 lines (132 loc) · 7.29 KB
/
FeatureProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using OpenFeature.Constant;
using OpenFeature.Model;
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // required to allow NSubstitute mocking of internal methods
namespace OpenFeature
{
/// <summary>
/// The provider interface describes the abstraction layer for a feature flag provider.
/// A provider acts as the translates layer between the generic feature flag structure to a target feature flag system.
/// </summary>
/// <seealso href="https://github.com/open-feature/spec/blob/v0.5.2/specification/sections/02-providers.md">Provider specification</seealso>
public abstract class FeatureProvider
{
/// <summary>
/// Gets a immutable list of hooks that belong to the provider.
/// By default return a empty list
///
/// Executed in the order of hooks
/// before: API, Client, Invocation, Provider
/// after: Provider, Invocation, Client, API
/// error (if applicable): Provider, Invocation, Client, API
/// finally: Provider, Invocation, Client, API
/// </summary>
/// <returns>Immutable list of hooks</returns>
public virtual IImmutableList<Hook> GetProviderHooks() => ImmutableList<Hook>.Empty;
/// <summary>
/// The event channel of the provider.
/// </summary>
protected readonly Channel<object> EventChannel = Channel.CreateBounded<object>(1);
/// <summary>
/// Metadata describing the provider.
/// </summary>
/// <returns><see cref="Metadata"/></returns>
public abstract Metadata GetMetadata();
/// <summary>
/// Resolves a boolean feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns><see cref="ResolutionDetails{T}"/></returns>
public abstract Task<ResolutionDetails<bool>> ResolveBooleanValueAsync(string flagKey, bool defaultValue,
EvaluationContext? context = null, CancellationToken cancellationToken = default);
/// <summary>
/// Resolves a string feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns><see cref="ResolutionDetails{T}"/></returns>
public abstract Task<ResolutionDetails<string>> ResolveStringValueAsync(string flagKey, string defaultValue,
EvaluationContext? context = null, CancellationToken cancellationToken = default);
/// <summary>
/// Resolves a integer feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns><see cref="ResolutionDetails{T}"/></returns>
public abstract Task<ResolutionDetails<int>> ResolveIntegerValueAsync(string flagKey, int defaultValue,
EvaluationContext? context = null, CancellationToken cancellationToken = default);
/// <summary>
/// Resolves a double feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns><see cref="ResolutionDetails{T}"/></returns>
public abstract Task<ResolutionDetails<double>> ResolveDoubleValueAsync(string flagKey, double defaultValue,
EvaluationContext? context = null, CancellationToken cancellationToken = default);
/// <summary>
/// Resolves a structured feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns><see cref="ResolutionDetails{T}"/></returns>
public abstract Task<ResolutionDetails<Value>> ResolveStructureValueAsync(string flagKey, Value defaultValue,
EvaluationContext? context = null, CancellationToken cancellationToken = default);
/// <summary>
/// Internally-managed provider status.
/// The SDK uses this field to track the status of the provider.
/// Not visible outside OpenFeature assembly
/// </summary>
internal virtual ProviderStatus Status { get; set; } = ProviderStatus.NotReady;
/// <summary>
/// <para>
/// This method is called before a provider is used to evaluate flags. Providers can overwrite this method,
/// if they have special initialization needed prior being called for flag evaluation.
/// When this method completes, the provider will be considered ready for use.
/// </para>
/// </summary>
/// <param name="context"><see cref="EvaluationContext"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to cancel any async side effects.</param>
/// <returns>A task that completes when the initialization process is complete.</returns>
/// <remarks>
/// <para>
/// Providers not implementing this method will be considered ready immediately.
/// </para>
/// </remarks>
public virtual Task InitializeAsync(EvaluationContext context, CancellationToken cancellationToken = default)
{
// Intentionally left blank.
return Task.CompletedTask;
}
/// <summary>
/// This method is called when a new provider is about to be used to evaluate flags, or the SDK is shut down.
/// Providers can overwrite this method, if they have special shutdown actions needed.
/// </summary>
/// <returns>A task that completes when the shutdown process is complete.</returns>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to cancel any async side effects.</param>
public virtual Task ShutdownAsync(CancellationToken cancellationToken = default)
{
// Intentionally left blank.
return Task.CompletedTask;
}
/// <summary>
/// Returns the event channel of the provider.
/// </summary>
/// <returns>The event channel of the provider</returns>
public virtual Channel<object> GetEventChannel() => this.EventChannel;
}
}