Skip to content

Commit 3db4b0e

Browse files
committed
feat: Add tracking event handling to MultiProvider and evaluation strategy
Signed-off-by: André Silva <[email protected]>
1 parent 29e1657 commit 3db4b0e

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/OpenFeature.Providers.MultiProvider/MultiProvider.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,37 @@ public override Task<ResolutionDetails<string>> ResolveStringValueAsync(string f
113113
public override Task<ResolutionDetails<Value>> ResolveStructureValueAsync(string flagKey, Value defaultValue, EvaluationContext? context = null, CancellationToken cancellationToken = default) =>
114114
this.EvaluateAsync(flagKey, defaultValue, context, cancellationToken);
115115

116+
/// <inheritdoc/>
117+
public override void Track(string trackingEventName, EvaluationContext? evaluationContext = default, TrackingEventDetails? trackingEventDetails = default)
118+
{
119+
if (this._disposed == 1)
120+
{
121+
throw new ObjectDisposedException(nameof(MultiProvider));
122+
}
123+
124+
foreach (var registeredProvider in this._registeredProviders)
125+
{
126+
var providerContext = new StrategyPerProviderContext<object>(
127+
registeredProvider.Provider,
128+
registeredProvider.Name,
129+
registeredProvider.Status,
130+
string.Empty); // Empty flag key for tracking context
131+
132+
if (this._evaluationStrategy.ShouldTrackWithThisProvider(providerContext, evaluationContext, trackingEventName, trackingEventDetails))
133+
{
134+
try
135+
{
136+
registeredProvider.Provider.Track(trackingEventName, evaluationContext, trackingEventDetails);
137+
}
138+
catch (Exception ex)
139+
{
140+
// Log tracking errors but don't throw - tracking should not disrupt application flow
141+
this.LogErrorTrackingEvent(registeredProvider.Name, trackingEventName, ex);
142+
}
143+
}
144+
}
145+
}
146+
116147
/// <inheritdoc/>
117148
public override async Task InitializeAsync(EvaluationContext context, CancellationToken cancellationToken = default)
118149
{
@@ -638,4 +669,7 @@ internal void SetStatus(ProviderStatus providerStatus)
638669

639670
[LoggerMessage(EventId = 1, Level = LogLevel.Debug, Message = "Provider {ProviderName} is already being listened to")]
640671
private partial void LogProviderAlreadyBeingListenedTo(string providerName);
672+
673+
[LoggerMessage(EventId = 2, Level = LogLevel.Debug, Message = "Error tracking event {TrackingEventName} with provider {ProviderName}")]
674+
private partial void LogErrorTrackingEvent(string providerName, string trackingEventName, Exception exception);
641675
}

src/OpenFeature.Providers.MultiProvider/Strategies/BaseEvaluationStrategy.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,20 @@ public virtual bool ShouldEvaluateNextProvider<T>(StrategyPerProviderContext<T>
5858
/// <returns>The final evaluation result.</returns>
5959
public abstract FinalResult<T> DetermineFinalResult<T>(StrategyEvaluationContext<T> strategyContext, string key, T defaultValue, EvaluationContext? evaluationContext, List<ProviderResolutionResult<T>> resolutions);
6060

61+
/// <summary>
62+
/// Determines whether a specific provider should receive tracking events.
63+
/// </summary>
64+
/// <param name="strategyContext">Context information about the provider.</param>
65+
/// <param name="evaluationContext">The evaluation context for the tracking event.</param>
66+
/// <param name="trackingEventName">The name of the tracking event.</param>
67+
/// <param name="trackingEventDetails">The tracking event details.</param>
68+
/// <returns>True if the provider should receive tracking events, false otherwise.</returns>
69+
public virtual bool ShouldTrackWithThisProvider(StrategyPerProviderContext<object> strategyContext, EvaluationContext? evaluationContext, string trackingEventName, TrackingEventDetails? trackingEventDetails)
70+
{
71+
// By default, track with providers that are ready
72+
return strategyContext.ProviderStatus == ProviderStatus.Ready;
73+
}
74+
6175
/// <summary>
6276
/// Checks if a resolution result represents an error.
6377
/// </summary>

0 commit comments

Comments
 (0)