Skip to content

feat: Added hook data#1506

Closed
mdxabu wants to merge 12 commits into
open-feature:mainfrom
mdxabu:main
Closed

feat: Added hook data#1506
mdxabu wants to merge 12 commits into
open-feature:mainfrom
mdxabu:main

Conversation

@mdxabu

@mdxabu mdxabu commented Jul 6, 2025

Copy link
Copy Markdown
Contributor

This PR

Added the Hook Data

  • adds this new feature

Related Issues

Fixes #1472

@beeme1mr, Please review this if there is any problem or if I did anything wrong, ping me!

@mdxabu
mdxabu requested review from a team as code owners July 6, 2025 11:07
@mdxabu mdxabu changed the title Added hook data feat: Added hook data Jul 6, 2025
Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
Comment thread src/main/java/dev/openfeature/sdk/HookContext.java
@chrfwow

chrfwow commented Jul 7, 2025

Copy link
Copy Markdown
Contributor

@mdxabu you will need to force push a commit that is signed off, otherwise the DCO check will not succeed

@mdxabu

mdxabu commented Jul 7, 2025

Copy link
Copy Markdown
Contributor Author

@mdxabu you will need to force push a commit that is signed off, otherwise the DCO check will not succeed

Can I squash those commits into one commit, and then I will sign off?

@chrfwow

chrfwow commented Jul 7, 2025

Copy link
Copy Markdown
Contributor

Can I squash those commits into one commit, and then I will sign off?

Yes, you could do that. If you click on the failed DCO action, you schould see a short explanation

mdxabu added 2 commits July 7, 2025 21:23
Signed-off-by: mdxabu <abdullahfakrudeen2020@gmail.com>
…d ConcurrentHashMap and use a synchronized HashMap instead

Signed-off-by: mdxabu <abdullahfakrudeen2020@gmail.com>
@mdxabu

mdxabu commented Jul 7, 2025

Copy link
Copy Markdown
Contributor Author

@chrfwow, I force push the commits! Now DCO action runs successfully.

@mdxabu
mdxabu requested a review from chrfwow July 8, 2025 04:54
@chrfwow

chrfwow commented Jul 8, 2025

Copy link
Copy Markdown
Contributor

The build currently fails because of formatting issues. You can resolve them automatically by running the spotless plugin

Signed-off-by: mdxabu <abdullahfakrudeen2020@gmail.com>
@codecov

codecov Bot commented Jul 8, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.35%. Comparing base (8dd40fa) to head (f3ea94d).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #1506      +/-   ##
============================================
+ Coverage     92.82%   93.35%   +0.53%     
- Complexity      487      492       +5     
============================================
  Files            46       47       +1     
  Lines          1170     1189      +19     
  Branches        103      107       +4     
============================================
+ Hits           1086     1110      +24     
+ Misses           54       49       -5     
  Partials         30       30              
Flag Coverage Δ
unittests 93.35% <100.00%> (+0.53%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2025

Copy link
Copy Markdown

* Each hook instance gets its own isolated data store that persists only for the duration
* of a single flag evaluation.
*/
public interface HookData {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We may be able to use some of the functionality in Structure or it's implementations to do this. We don't need all of those methods, but some wouldn't hurt, I think, and it would reduce duplication and promote consistency.

@alexandraoberaigner alexandraoberaigner Sep 8, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@toddbaert I took a closer look and found that Structure enforces that all stored data must be of type Value, which conflicts with the OPENFEATURE SPEC allowing values of any type in hookdata. This restriction makes Structure unsuitable for hook data. As far as I understand it, sticking with @mdxabu 's implementation aligns better with the spec. Pls let me know if I missed anything! 🙏

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, but can use lombok to delegate only some methods.

@aepfli what do you think? You have been working on improving consistency of our POJOs... what is you opinion on this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am actually questioning some of my rewokr based on this findings. -> yes we do have the need for some POJO's to contain only string/numbers/booleans/etc - but i am not sure we need this kind of structure for all of them. especially like the hookcontext is not used for futher evaluation etc. it is used within the same hook, and can have any kind of data. i think that a pure object map would be sufficient in this case. and we should allow all kind of objects (structure limits this, but structure has a dedicated usage for certain operations)

@alexandraoberaigner

Copy link
Copy Markdown
Contributor

@mdxabu how is it going? We do have an internal dependency on this. Can we support somehow? :)

@mdxabu

mdxabu commented Sep 1, 2025

Copy link
Copy Markdown
Contributor Author

Yeah, Sure!

@alexandraoberaigner

Copy link
Copy Markdown
Contributor

Yeah, Sure!

Great, let me know how I can support :)

Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
aepfli and others added 2 commits September 9, 2025 17:31
Co-authored-by: alexandraoberaigner <82218944+alexandraoberaigner@users.noreply.github.com>
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Co-authored-by: alexandraoberaigner <82218944+alexandraoberaigner@users.noreply.github.com>
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>

@aepfli aepfli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side. Thank you for the great and valuable addition. I think this will make sharing data between hook steps way easier. Thank you!

Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
Comment thread src/main/java/dev/openfeature/sdk/HookData.java Outdated
Comment on lines +92 to +98
// Create hook data for each hook instance
Map<Hook, HookData> hookDataMap = new HashMap<>();
for (Hook hook : reversedHooks) {
if (hook.supportsFlagValueType(flagValueType)) {
hookDataMap.put(hook, HookData.create());
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need this map and loop? We don't return the map, so it will be GC'ed after the method returns, and we could create the HookData in the loop below like this:
HookContext contextWithHookData = hookCtx.withHookData(HookData.create());

Comment on lines +75 to +101
@Test
void shouldBeThreadSafe() throws InterruptedException {
HookData hookData = HookData.create();
int threadCount = 10;
int operationsPerThread = 100;
CountDownLatch latch = new CountDownLatch(threadCount);
ExecutorService executor = Executors.newFixedThreadPool(threadCount);

for (int i = 0; i < threadCount; i++) {
final int threadId = i;
executor.submit(() -> {
try {
for (int j = 0; j < operationsPerThread; j++) {
String key = "thread-" + threadId + "-key-" + j;
String value = "thread-" + threadId + "-value-" + j;
hookData.set(key, value);
assertEquals(value, hookData.get(key));
}
} finally {
latch.countDown();
}
});
}

assertTrue(latch.await(10, TimeUnit.SECONDS));
executor.shutdown();
}

@chrfwow chrfwow Sep 10, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd expect this test to fail. HookData is not thread safe anymore. We can remove this test. (In the future, such tests should be done with VmLens, but that is not merged yet)

return baseContext;
}

private static class TestHook implements Hook<String> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems to be unused

mdxabu and others added 2 commits September 10, 2025 12:01
Co-authored-by: chrfwow <christian.lutnik@dynatrace.com>
Signed-off-by: Abu <abdullahfakrudeen2020@gmail.com>
Co-authored-by: chrfwow <christian.lutnik@dynatrace.com>
Signed-off-by: Abu <abdullahfakrudeen2020@gmail.com>
@sonarqubecloud

Copy link
Copy Markdown

@aepfli

aepfli commented Sep 15, 2025

Copy link
Copy Markdown
Member

hey @mdxabu - we took a look at your implementation and it is a good foundation, but we have seen some issues, with how data was enriched, and also with the object churn (creating a lot of objects). So we gave it a shot on our own here #1587 - we used your pr as a basis, and we will keep all of your commits. we just wanted to make sure you are okay with this. Thank you for the effort and the foundation.

@mdxabu

mdxabu commented Sep 15, 2025

Copy link
Copy Markdown
Contributor Author

#1587

Yeah, I'm okay with that. I'm glad you're asking for my opinion! I like this community!

@aepfli aepfli closed this Sep 15, 2025
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.

Add Hook Data

6 participants