From e261d9bc3007f131c905a1dbd54cb1878e7fff23 Mon Sep 17 00:00:00 2001 From: DouglasHammon-FV <132104255+DouglasHammon-FV@users.noreply.github.com> Date: Mon, 18 Sep 2023 18:04:45 -0600 Subject: [PATCH] Update OpenFeatureClient.cs bugfix(feature-client): Added configure await to avoid deadlocks when executing synchronously Signed-off-by: DouglasHammon-FV <132104255+DouglasHammon-FV@users.noreply.github.com> --- src/OpenFeature/OpenFeatureClient.cs | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/OpenFeature/OpenFeatureClient.cs b/src/OpenFeature/OpenFeatureClient.cs index 38a0fd63..1cc26802 100644 --- a/src/OpenFeature/OpenFeatureClient.cs +++ b/src/OpenFeature/OpenFeatureClient.cs @@ -107,63 +107,63 @@ public FeatureClient(string name, string version, ILogger logger = null, Evaluat /// public async Task GetBooleanValue(string flagKey, bool defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => - (await this.GetBooleanDetails(flagKey, defaultValue, context, config)).Value; + (await this.GetBooleanDetails(flagKey, defaultValue, context, config).ConfigureAwait(false)).Value; /// public async Task> GetBooleanDetails(string flagKey, bool defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => await this.EvaluateFlag(this.ExtractProvider(provider => provider.ResolveBooleanValue), FlagValueType.Boolean, flagKey, - defaultValue, context, config); + defaultValue, context, config).ConfigureAwait(false); /// public async Task GetStringValue(string flagKey, string defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => - (await this.GetStringDetails(flagKey, defaultValue, context, config)).Value; + (await this.GetStringDetails(flagKey, defaultValue, context, config).ConfigureAwait(false)).Value; /// public async Task> GetStringDetails(string flagKey, string defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => await this.EvaluateFlag(this.ExtractProvider(provider => provider.ResolveStringValue), FlagValueType.String, flagKey, - defaultValue, context, config); + defaultValue, context, config).ConfigureAwait(false); /// public async Task GetIntegerValue(string flagKey, int defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => - (await this.GetIntegerDetails(flagKey, defaultValue, context, config)).Value; + (await this.GetIntegerDetails(flagKey, defaultValue, context, config).ConfigureAwait(false)).Value; /// public async Task> GetIntegerDetails(string flagKey, int defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => await this.EvaluateFlag(this.ExtractProvider(provider => provider.ResolveIntegerValue), FlagValueType.Number, flagKey, - defaultValue, context, config); + defaultValue, context, config).ConfigureAwait(false); /// public async Task GetDoubleValue(string flagKey, double defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => - (await this.GetDoubleDetails(flagKey, defaultValue, context, config)).Value; + (await this.GetDoubleDetails(flagKey, defaultValue, context, config).ConfigureAwait(false)).Value; /// public async Task> GetDoubleDetails(string flagKey, double defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => await this.EvaluateFlag(this.ExtractProvider(provider => provider.ResolveDoubleValue), FlagValueType.Number, flagKey, - defaultValue, context, config); + defaultValue, context, config).ConfigureAwait(false); /// public async Task GetObjectValue(string flagKey, Value defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => - (await this.GetObjectDetails(flagKey, defaultValue, context, config)).Value; + (await this.GetObjectDetails(flagKey, defaultValue, context, config).ConfigureAwait(false)).Value; /// public async Task> GetObjectDetails(string flagKey, Value defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null) => await this.EvaluateFlag(this.ExtractProvider(provider => provider.ResolveStructureValue), FlagValueType.Object, flagKey, - defaultValue, context, config); + defaultValue, context, config).ConfigureAwait(false); private async Task> EvaluateFlag( (Func>>, FeatureProvider) providerInfo, @@ -211,13 +211,13 @@ private async Task> EvaluateFlag( FlagEvaluationDetails evaluation; try { - var contextFromHooks = await this.TriggerBeforeHooks(allHooks, hookContext, options); + var contextFromHooks = await this.TriggerBeforeHooks(allHooks, hookContext, options).ConfigureAwait(false); evaluation = - (await resolveValueDelegate.Invoke(flagKey, defaultValue, contextFromHooks.EvaluationContext)) + (await resolveValueDelegate.Invoke(flagKey, defaultValue, contextFromHooks.EvaluationContext).ConfigureAwait(false)) .ToFlagEvaluationDetails(); - await this.TriggerAfterHooks(allHooksReversed, hookContext, evaluation, options); + await this.TriggerAfterHooks(allHooksReversed, hookContext, evaluation, options).ConfigureAwait(false); } catch (FeatureProviderException ex) { @@ -225,18 +225,18 @@ private async Task> EvaluateFlag( ex.ErrorType.GetDescription()); evaluation = new FlagEvaluationDetails(flagKey, defaultValue, ex.ErrorType, Reason.Error, string.Empty, ex.Message); - await this.TriggerErrorHooks(allHooksReversed, hookContext, ex, options); + await this.TriggerErrorHooks(allHooksReversed, hookContext, ex, options).ConfigureAwait(false); } catch (Exception ex) { this._logger.LogError(ex, "Error while evaluating flag {FlagKey}", flagKey); var errorCode = ex is InvalidCastException ? ErrorType.TypeMismatch : ErrorType.General; evaluation = new FlagEvaluationDetails(flagKey, defaultValue, errorCode, Reason.Error, string.Empty); - await this.TriggerErrorHooks(allHooksReversed, hookContext, ex, options); + await this.TriggerErrorHooks(allHooksReversed, hookContext, ex, options).ConfigureAwait(false); } finally { - await this.TriggerFinallyHooks(allHooksReversed, hookContext, options); + await this.TriggerFinallyHooks(allHooksReversed, hookContext, options).ConfigureAwait(false); } return evaluation; @@ -250,7 +250,7 @@ private async Task> TriggerBeforeHooks(IReadOnlyList hoo foreach (var hook in hooks) { - var resp = await hook.Before(context, options?.HookHints); + var resp = await hook.Before(context, options?.HookHints).ConfigureAwait(false); if (resp != null) { evalContextBuilder.Merge(resp); @@ -271,7 +271,7 @@ private async Task TriggerAfterHooks(IReadOnlyList hooks, HookContext(IReadOnlyList hooks, HookContext(IReadOnlyList hooks, HookContext { try { - await hook.Finally(context, options?.HookHints); + await hook.Finally(context, options?.HookHints).ConfigureAwait(false); } catch (Exception e) {