Skip to content

[FFL-1579] Add callback support to setEvaluationContext method#3056

Merged
dd-mergequeue[bot] merged 7 commits into
developfrom
typo/FFL-1579-sdk-android-expose-callback-for-set-evaluation-context-method-call
Dec 17, 2025
Merged

[FFL-1579] Add callback support to setEvaluationContext method#3056
dd-mergequeue[bot] merged 7 commits into
developfrom
typo/FFL-1579-sdk-android-expose-callback-for-set-evaluation-context-method-call

Conversation

@typotter

@typotter typotter commented Dec 15, 2025

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds an optional callback parameter to the FlagsClient.setEvaluationContext() method to enable applications - and Openfeature SDK modules built ontop of flags to block and wait for the completion of the async network request triggered by this method.

Motivation

The current setEvaluationContext() method is fire-and-forget, making it difficult for applications to:

  • Know when flag evaluations have been fetched and are ready to use
  • Handle network failures when updating evaluation context
  • Coordinate downstream operations that depend on updated flag values

This change adds a standard callback interface (EvaluationContextCallback) that follows existing SDK patterns (e.g., DataStoreWriteCallback) to notify callers of success or failure.

Implementation Details

New Public API:

  • Created EvaluationContextCallback interface with onSuccess() and onFailure(error: Throwable) methods
  • Updated FlagsClient.setEvaluationContext() to accept optional callback parameter
  • Callbacks are invoked on background executor thread after state transitions

Callback Semantics:

  • onSuccess() - Called when state transitions to FlagsClientState.Ready (network fetch succeeded)
  • onFailure(error) - Called when state transitions to FlagsClientState.Stale or FlagsClientState.Error (network request failed)
  • NoOpFlagsClient invokes onSuccess() for graceful degradation consistency

Thread Safety:

  • Callbacks execute on the same background executor thread as state notifications
  • Protected by existing executeSafe() exception handling
  • No additional synchronization overhead

Additional Notes

Design Decisions:

  • Used interface callback (not lambdas) to match existing SDK callback patterns
  • Backward compatible - callback parameter is optional with default null

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)

@typotter
typotter requested a review from yugisu-flux December 15, 2025 21:33
@typotter
typotter marked this pull request as ready for review December 15, 2025 21:52
@typotter
typotter requested a review from a team as a code owner December 15, 2025 21:52
@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Dec 15, 2025

Copy link
Copy Markdown

🎯 Code Coverage
Patch Coverage: 100.00%
Overall Coverage: 66.28% (-5.22%)

View detailed report

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 1088bcd | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@codecov-commenter

codecov-commenter commented Dec 15, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.77778% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.28%. Comparing base (ed7f4e1) to head (1088bcd).
⚠️ Report is 939 commits behind head on develop.

Files with missing lines Patch % Lines
...in/kotlin/com/datadog/android/flags/FlagsClient.kt 0.00% 1 Missing ⚠️
...id/flags/internal/evaluation/EvaluationsManager.kt 80.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3056      +/-   ##
===========================================
+ Coverage    71.24%   71.28%   +0.04%     
===========================================
  Files          866      867       +1     
  Lines        31730    31729       -1     
  Branches      5360     5362       +2     
===========================================
+ Hits         22604    22615      +11     
+ Misses        7602     7591      -11     
+ Partials      1524     1523       -1     
Files with missing lines Coverage Δ
...tadog/android/flags/internal/DatadogFlagsClient.kt 89.86% <100.00%> (-1.45%) ⬇️
.../datadog/android/flags/internal/NoOpFlagsClient.kt 93.33% <100.00%> (+0.23%) ⬆️
...lags/internal/net/NetworkRequestFailedException.kt 100.00% <100.00%> (ø)
...in/kotlin/com/datadog/android/flags/FlagsClient.kt 34.21% <0.00%> (-1.38%) ⬇️
...id/flags/internal/evaluation/EvaluationsManager.kt 89.47% <80.00%> (-1.70%) ⬇️

... and 39 files with indirect coverage changes

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

0xnm
0xnm previously approved these changes Dec 16, 2025

@0xnm 0xnm 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.

Some minor comments/suggestions only.

The only major comment is to avoid passing generic Throwable and switch to the more precise exception.

{ NETWORK_REQUEST_FAILED_MESSAGE }
)

val throwable = Throwable(NETWORK_REQUEST_FAILED_MESSAGE)

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.

minor: it is better to avoid creating generic Throwable. Probably here it is better to create some NetworkCallFailedException: RuntimeException and pass it instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done, thanks!

yugisu-flux
yugisu-flux previously approved these changes Dec 16, 2025

@yugisu-flux yugisu-flux left a comment

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.

Looks great, thanks for adding this! (+1 to Nikita's feedback)

Co-authored-by: Nikita Ogorodnikov <[email protected]>
@typotter
typotter dismissed stale reviews from yugisu-flux and 0xnm via 2fbb979 December 16, 2025 15:26

@typotter typotter left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks Nikita. PTAL

{ NETWORK_REQUEST_FAILED_MESSAGE }
)

val throwable = Throwable(NETWORK_REQUEST_FAILED_MESSAGE)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done, thanks!

0xnm
0xnm previously approved these changes Dec 16, 2025

@0xnm 0xnm 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.

lgtm, but I think that exception class can be made internal, see my comment below.

*
* @param message A descriptive message about the network failure
*/
class NetworkRequestFailedException(message: String) : RuntimeException(message)

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.

minor: if there is no intention to expose the type to the user to do some matching, we can simply make it internal. And probably we should do that, because this is the only exception type we can propagate so far, so there is no alternatives to match against in the user code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done!

yugisu-flux
yugisu-flux previously approved these changes Dec 17, 2025
@typotter
typotter dismissed stale reviews from yugisu-flux and 0xnm via 422e856 December 17, 2025 15:42
@typotter
typotter requested a review from 0xnm December 17, 2025 15:42

@typotter typotter left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks Nikita. Just need a final stamp for the last change.

@typotter

Copy link
Copy Markdown
Contributor Author

/merge

@dd-devflow-routing-codex

dd-devflow-routing-codex Bot commented Dec 17, 2025

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2025-12-17 15:43:11 UTC ℹ️ Start processing command /merge


2025-12-17 15:43:17 UTC ℹ️ MergeQueue: waiting for PR to be ready

This pull request is not mergeable according to GitHub. Common reasons include pending required checks, missing approvals, or merge conflicts — but it could also be blocked by other repository rules or settings.
It will be added to the queue as soon as checks pass and/or get approvals.
Note: if you pushed new commits since the last approval, you may need additional approval.
You can remove it from the waiting list with /remove command.


2025-12-17 17:51:16 UTC ℹ️ MergeQueue: merge request added to the queue

The expected merge time in develop is approximately 0s (p90).


2025-12-17 18:49:46 UTCMergeQueue: The checks failed on this merge request

Tests failed on this commit 6ca8cba:

What to do next?

  • Investigate the failures and when ready, re-add your pull request to the queue!
  • If your PR checks are green, try to rebase/merge. It might be because the CI run is a bit old.
  • Any question, go check the FAQ.

0xnm
0xnm previously approved these changes Dec 17, 2025
@typotter
typotter force-pushed the typo/FFL-1579-sdk-android-expose-callback-for-set-evaluation-context-method-call branch from 13f51d7 to 96404fa Compare December 17, 2025 16:05

@typotter typotter left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry Nikita. Missed moving the exception to the internal.net package
Please stamp again.

@typotter
typotter requested a review from 0xnm December 17, 2025 16:06
0xnm
0xnm previously approved these changes Dec 17, 2025
@typotter

Copy link
Copy Markdown
Contributor Author

/merge

@dd-devflow-routing-codex

dd-devflow-routing-codex Bot commented Dec 17, 2025

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2025-12-17 19:01:06 UTC ℹ️ Start processing command /merge


2025-12-17 19:01:11 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in develop is approximately 0s (p90).


2025-12-17 19:58:00 UTC ℹ️ MergeQueue: This merge request was merged

@dd-mergequeue
dd-mergequeue Bot merged commit 9b80008 into develop Dec 17, 2025
27 of 28 checks passed
@dd-mergequeue
dd-mergequeue Bot deleted the typo/FFL-1579-sdk-android-expose-callback-for-set-evaluation-context-method-call branch December 17, 2025 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants