-
Notifications
You must be signed in to change notification settings - Fork 94
chore(ADR): Create fractional-non-string-rand-units.md #1783
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
Conversation
For #1737 Signed-off-by: cupofcat <[email protected]>
✅ Deploy Preview for polite-licorice-3db33c ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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.
Summary of Changes
Hello @cupofcat, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces a new Architecture Decision Record (ADR) proposing an enhancement to the fractional operator in flagd. The core purpose is to enable the fractional operator to directly support non-string input values for hashing, such as integers or booleans, without requiring explicit string coercion. This change aims to improve consistency across different provider implementations and simplify flag definitions by allowing direct use of various data types for bucketing.
Highlights
- Fractional Operator Enhancement: Proposes an Architecture Decision Record (ADR) to allow the fractional operator to accept non-string inputs (e.g., integers, booleans) for hashing, eliminating the need for explicit string coercion.
- Improved Hashing Consistency: Addresses current inconsistencies in hashing across different provider implementations (Go, JS) by proposing direct byte representation hashing for non-string inputs, while maintaining backward compatibility for existing string-based inputs.
- No Schema Changes: The proposed change is purely semantic, affecting only the evaluation logic within flagd providers, and introduces no modifications to the existing flagd JSON schema.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
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.
Code Review
This pull request introduces an Architecture Decision Record (ADR) to support non-string inputs for fractional bucketing, which is a valuable enhancement for flagd. The ADR is well-structured and clearly outlines the problem, proposed solution, and consequences. My review focuses on improving the clarity and correctness of the document. I've provided suggestions to fix an invalid JSON example, correct list formatting, and resolve a critical ambiguity in the byte representation of non-string types to ensure cross-platform consistency. A few minor typos have also been identified for correction.
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
Signed-off-by: Maks Osowski <[email protected]>
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
|
I've been thinking about this more and I wonder WDYT about this approach: We take this pre-1.0 opportunity to introduce a breaking change for how hashing / bucketing works:
If the first argument is an object, it's evaluated and the evaluated value is passed to CBOR for marshalling into a consistent byte array. That byte array is passed to MurMur3 for hashing. If CBOR libraries in each language ensure that the same values get the same byte encoding and murmur3 libraries will ensure that same byte arrays will get the same hash. This works across any type, even for strings. That way we have langauge-agnostic, stable, and consistent bucketing. CBOR is specified in an Internet Standard RFC by IETF, which should mean this stays stable for foreseeable future. |
@cupofcat would you mind showing an example configuration of what you had in mind? When you say object, do you mean referencing a context attribute |
Edit: The above did not make sense, sorry. @beeme1mr I've been thinking about this more and I think we have the following options:
For (1), since the first argument is optional, we need a way to distinguish it from the subsequent ones. Today, this is done based on type (if it casts to a string, it's treated specially). That means the first argument, if the user wants to use it for bucketing, cannot evaluate to an array. If it is an array we cannot distinguish it from the rest of (2) is much clearer, but the semantic of the current schema changes (the schema itself can stay the same). We make the first argument mandatory as the bucketing input. If it's (3A) Similarly to today, if the first value in fractional array is bytes we hash that. If not, we use the current behavior as is. "fractional": [
{
"cbor-8949-bytes": [{"var" : "$flagd.flagKey"}, {"var" : "some-var"}]
},
["a", 50], ...
](3B) Similarly to today, if the first value in fractional array is a map/dict we hash that. If not, we use the current behavior as is. "fractional": [
{
"object": {
"comment" : "Any keys are valid, we will just translate all of this to bytes (JSONLogic would still evaluate the values)",
"key1" : {"var" : "$flagd.flagKey"},
"key2" : {"var" : "some-var"},
"extra-salt" : "himalayan"
}
},
["a", 50], ...
]If none of the above works, perhaps there is also:
WDYT? P.S. What I find complicates this exercise is that today we send the entire contents of So I guess there is also:
|
…ator Signed-off-by: Maks Osowski <[email protected]>
Signed-off-by: Maks Osowski <[email protected]>
|
Based on the discussions on Slack I updated this ADR to focus on hashing improvements in the existing fractional only. |
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
…dings Signed-off-by: Maks Osowski <[email protected]>
|
I updated the ADR to explicitly require CBOR encodings + some other minor improvements based on feedback. |
Signed-off-by: Maks Osowski <[email protected]>
|
I would not necessarily consider this a special case for strings. It's a result of JSONLogic rather than flagd approach (JSON Logic has "cat" operator for strings but does not have anything like that for non-string types). We can fix that by implementing an additional custom operator. That way we keep the new approach backwards compatible with old configs (and, tbh, there is no way around this - "cat" is a feature of JSONLogic, not flagd, so we cannot really block it unless we do some hacks). |
docs/architecture-decisions/fractional-non-string-rand-units.md
Outdated
Show resolved
Hide resolved
I can accept that the "salting" only occurs in the string case, as long as we document it clearly. The main advantage of the "salting" is that it means that users don't end up in the same bucket for every fractional flag... but the nonstring situation is a corner case of a corner case here, so I don't want to block this ADR just for this. |
|



This PR
Support Non-String Inputs for Fractional BucketingADRRelated Issues
#1737