Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement transaction context #312

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

askpt
Copy link
Member

@askpt askpt commented Nov 11, 2024

Transaction Context

This pull request introduces transaction context propagation to the OpenFeature library. The changes include adding a new interface for transaction context propagation, implementing a no-op and an AsyncLocal-based propagator, and updating the API to support these propagators.

Related Issues

Fixes #243

Notes

Transaction Context Propagation:

API Enhancements:

@askpt askpt linked an issue Nov 11, 2024 that may be closed by this pull request
Copy link

codecov bot commented Nov 15, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 85.53%. Comparing base (2774b0d) to head (59ddca7).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #312      +/-   ##
==========================================
+ Coverage   85.17%   85.53%   +0.36%     
==========================================
  Files          36       38       +2     
  Lines        1477     1514      +37     
  Branches      150      153       +3     
==========================================
+ Hits         1258     1295      +37     
  Misses        188      188              
  Partials       31       31              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@lukas-reining lukas-reining left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice start! Left some thoughts and references to how we are doing it in the other languages.

src/OpenFeature/Model/TransactionContext.cs Outdated Show resolved Hide resolved
src/OpenFeature/Model/ContextBuilder.cs Outdated Show resolved Hide resolved
src/OpenFeature/Api.cs Outdated Show resolved Hide resolved
src/OpenFeature/Api.cs Outdated Show resolved Hide resolved
@askpt
Copy link
Member Author

askpt commented Nov 26, 2024

Nice start! Left some thoughts and references to how we are doing it in the other languages.

Thanks for the review @lukas-reining. I based the implementation on the JS client. I'll look into more detail on the Java version instead.

@askpt askpt force-pushed the askpt/243-feature-implement-transaction-context branch from 35b90bf to 9158a92 Compare December 4, 2024 17:05
@askpt askpt closed this Dec 10, 2024
@askpt askpt force-pushed the askpt/243-feature-implement-transaction-context branch from a0a7f36 to c471c06 Compare December 10, 2024 08:34
@askpt askpt reopened this Dec 10, 2024
@askpt askpt requested a review from lukas-reining December 20, 2024 08:52
@askpt askpt marked this pull request as ready for review December 20, 2024 08:52
@askpt askpt requested a review from a team as a code owner December 20, 2024 08:52
/// Return the transaction context propagator.
/// </summary>
/// <returns><see cref="ITransactionContextPropagator"/>the registered transaction context propagator</returns>
public ITransactionContextPropagator GetTransactionContextPropagator()
Copy link
Member

@toddbaert toddbaert Dec 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this accessor, if we need it for tests or internally that's fine, but let's make it internal in that case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the java-sdk implementation. I am happy to change it to internal if it is the expected behaviour.

Let me know if I should remove or mark it as internal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I didn't realize we implemented it there. I'm not of the opinion it's a great idea, but since it's also there it's not a blocker for me (it's not in the spec).

I can go either way... do you think we should have it?

Approving now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anyone outside of the client need to access the Transaction Context Propagator? Likely not...

I prefer to keep it internal so we expose what is necessary. But I don't like different language implementations going in different directions, and I don't know what the best approach is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to keep it internal so we expose what is necessary.

I agree.

But I don't like different language implementations going in different directions, and I don't know what the best approach is.

Of course I generally agree, that's why we have a spec, but there's always going to be some deviations and extras. If anything, we should probably deprecate the Java function and remove it eventually. I don't see it in JS either.

Copy link
Member Author

@askpt askpt Dec 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed visibility here: bf4dbb4

Signed-off-by: Todd Baert <[email protected]>
@toddbaert
Copy link
Member

toddbaert commented Dec 31, 2024

This looks right to me, though unless there's a good reason, I think we should remove this. Besides that I'm ready to approve.

I also pushed a small change to add docs to the README. @askpt please check them and make sure they make sense to you (it's a similar example to other SDKs).

Copy link
Member

@toddbaert toddbaert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving, but highlighting this thread: #312 (comment)

namespace OpenFeature;

/// <summary>
/// It is a no-op implementation of <see cref="ITransactionContextPropagator"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not consider this a No-Op implementation. Maybe this line should be moved to the NoOpTransactionContextPropagator?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Fixed with: 7a60997

@@ -221,6 +221,7 @@ private async Task<FlagEvaluationDetails<T>> EvaluateFlagAsync<T>(
evaluationContextBuilder.Merge(evaluationContext);
evaluationContextBuilder.Merge(this.GetContext());
evaluationContextBuilder.Merge(context);
evaluationContextBuilder.Merge(Api.Instance.GetTransactionContext());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Requirement 3.2.3, the order should be API (global; lowest precedence) - transaction - client - invocation - before hooks (highest precedence), so I believe evaluationContextBuilder.Merge(context); should be the last merge call.
I think we should alos have a test to verify the correct merge order.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Updated: 59ddca7

@toddbaert please review this part again 👍

{
// Arrange
var propagator = new AsyncLocalTransactionContextPropagator();
var evaluationContext = EvaluationContext.Empty;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should use a different value here, so that we can be sure that we actually get the value we stored in the propagator, and not just the default empty value

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed: 1769be8

{
// Arrange
var api = Api.Instance;
var evaluationContext = EvaluationContext.Empty;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed: 1769be8


```csharp
// registering the AsyncLocalTransactionContextPropagator
Api.Instance.SetTransactionContextPropagator(new AsyncLocalTransactionContextPropagator());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why don't we set a AsyncLocalTransactionContextPropagator as default value? Then the user would not have to set one manually first, which would remove one potential error source.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@askpt askpt requested a review from chrfwow January 2, 2025 15:22
Copy link
Contributor

@chrfwow chrfwow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] Implement transaction context
4 participants