-
Notifications
You must be signed in to change notification settings - Fork 15
[FFL-1284] Create datadog-ffe-ffi crate #1282
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
base: main
Are you sure you want to change the base?
Conversation
BenchmarksComparisonBenchmark execution time: 2025-10-29 22:47:58 Comparing candidate commit 2d4e32d in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 55 metrics, 2 unstable metrics. CandidateCandidate benchmark detailsGroup 1
Group 2
Group 3
Group 4
Group 5
Group 6
Group 7
Group 8
Group 9
Group 10
Group 11
Group 12
Group 13
Group 14
Group 15
Group 16
Group 17
BaselineOmitted due to size. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1282 +/- ##
==========================================
- Coverage 72.05% 71.96% -0.09%
==========================================
Files 368 371 +3
Lines 58076 58158 +82
==========================================
+ Hits 41847 41854 +7
- Misses 16229 16304 +75
🚀 New features to boost your workflow:
|
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
Creates C-compatible FFI layer for Feature Flagging & Experimentation: - Add datadog-ffe-ffi crate following ddsketch-ffi patterns - Implement Handle<T> wrappers for Configuration, EvaluationContext, Assignment - Export get_assignment, configuration_new, evaluation_context_new functions - Add memory management with drop functions - Generate C headers via cbindgen for Ruby integration - Update Cargo.toml to include new FFI crate in workspace
- Remove trailing whitespace from doc comments - Reformat function call in assignment.rs to fit line length constraints
553e2ac to
dfc60e3
Compare
- Updated build.rs to use a variable for the header name and improved readability. - Modified cbindgen.toml to reorganize export settings and enforce naming conventions for types and functions. - Added Clippy lints in lib.rs to enhance code quality and prevent common pitfalls.
| [package] | ||
| name = "datadog-ffe-ffi" | ||
| edition.workspace = true | ||
| version = "0.1.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To match with
libdatadog/datadog-ffe/Cargo.toml
Line 3 in 7e0063f
| version = "0.1.0" |
to indicate that
datadog-ffe-ffi is not production ready
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can pin this, so that datadog-ffe and datadog-ffe-ffi versions are always aligned? Maybe we should put FFI functions into datadog-ffe directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a temporary issue. When FFI is ready, we can update datadog-ffe/Cargo.toml and datadog-ffe-ffi/Cargo.toml to
version.workspace = true # Would use "22.1.0"
From
Line 68 in a0e4bff
| version = "22.1.0" |
Also the version in the dependency should cause a build failure, which is another way of ensuring that they match
libdatadog/datadog-ffe-ffi/Cargo.toml
Line 24 in c453cb9
| datadog-ffe = { path = "../datadog-ffe", version = "=0.1.0" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we will not use the workspace version.
- It doesn't really suit us to have use the workspace version as it makes version bumps more complicated requiring cross-team alignment without any benefit
- libdatadog is migrating into the direction of each package having its own version
Pin datadog-ffe to exact version Co-authored-by: Oleksii Shmalko <[email protected]>
refactor(ffe): simplify error handling Merge branch 'sameerank/FFL-1284-Create-datadog-ffe-ffi-crate' into ffe-simplify-error-handling Co-authored-by: sameerank <[email protected]>
Replace ddog_ffe_evaluation_context_new_with_attribute with ddog_ffe_evaluation_context_new_with_attributes that accepts an array of AttributePair structs.
Handle take() errors gracefully in ddog_ffe_configuration_drop and ddog_ffe_assignment_drop to prevent malloc corruption from double-free or use-after-free scenarios. Previously, take() failures would panic and cause "pointer being freed was not allocated" errors.
- Changed the `context` parameter in `ddog_ffe_get_assignment` to be a pointer for consistency. - Removed the single-attribute constructor `ddog_ffe_evaluation_context_new` and updated the multi-attribute constructor's documentation for clarity.
| let config = config.to_inner_mut()?; | ||
| let context = context.to_inner_mut()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor (postpone for now): .to_inner_mut() is creating &mut references which is unsound/unsafe with multi-threading. We'll need to migrate to using const-references in the future
| let assignment_result = get_assignment(Some(config), flag_key, context, None, now())?; | ||
|
|
||
| let handle = if let Some(assignment) = assignment_result { | ||
| Handle::from(assignment) | ||
| } else { | ||
| Handle::empty() | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
major: ? is stripping all of the error details which are going to be important to populate reason/error_code/error_message openfeature fields. We need to return a new structure that would accurately preserve error codes, similarly to ResolutionDetails in DataDog/dd-trace-py#15098
| mut config: *mut Handle<Configuration>, | ||
| flag_key: *const c_char, | ||
| mut context: *mut Handle<EvaluationContext>, | ||
| ) -> Result<Handle<Assignment>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
major(?): is Ruby able to access fields directly (I guess not?) or we need to provide accessor methods?
| targeting_key: *const c_char, | ||
| attributes: *const AttributePair, | ||
| attributes_count: usize, | ||
| ) -> Handle<EvaluationContext> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: consider using similar error-handling pattern here
| Str::from(name_str.to_string()), | ||
| Attribute::from(value_str.to_string()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: this seems to do unnecessary allocation of String: CStr -> &str -> String -> Str. We shall be able to go directly from &str to Str:
| Str::from(name_str.to_string()), | |
| Attribute::from(value_str.to_string()), | |
| Str::from(name_str), | |
| Attribute::from(value_str), |
| #[repr(C)] | ||
| pub struct AttributePair { | ||
| pub name: *const c_char, | ||
| pub value: *const c_char, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
major: how does this work for numeric and boolean attributes?
What does this PR do?
Adds a
datadog-ffe-fficrate, which provides a C FFI (Foreign Function Interface) bindings for thedatadog-ffe(Feature Flag Evaluation) library. This is to allowdd-trace-rbto interact with the feature flag evaluation engine through a C-compatible API.The crate exposes the following key components:
Motivation
The motivation for FFL-1284 is to enable non-Rust languages (PHP, Ruby, Python, etc.) to use the feature flag evaluator in
libdatadog, for consistent feature flag evaluation in SDKs across languages.Additional Notes
datadog-profiling-ffi,datadog-crashtracker-ffi)cbindgenfor automatic C generationstaticlib,cdylib)How to test the change?
cargo build -p datadog-ffe-fficargo build -p datadog-ffe-ffi --features cbindgen(Check that headers are generated intarget/include/)[FFL-1273] bindings for libdatadog datadog ffe api dd-trace-rb#5001[FFL-1273] bindings for ffe in openfeature provider dd-trace-rb#5007