Skip to content

feat: add InMemoryProvider context callbacks and event emission#224

Merged
josecolella merged 3 commits intomainfrom
feat/in-memory-provider-context-events
Mar 5, 2026
Merged

feat: add InMemoryProvider context callbacks and event emission#224
josecolella merged 3 commits intomainfrom
feat/in-memory-provider-context-events

Conversation

@josecolella
Copy link
Collaborator

Summary

  • Support callable (Proc/lambda) flag values that receive evaluation context, enabling dynamic flag resolution per Appendix A
  • Include Provider::EventEmitter in InMemoryProvider for lifecycle event emission
  • add_flag now emits PROVIDER_CONFIGURATION_CHANGED when attached to configuration
  • Add update_flags method to replace entire flag set with event emission
  • Remove completed TODO comments
  • Update provider compatibility tests to reflect EventEmitter inclusion

Spec References

Part of the spec compliance roadmap: #220

Test plan

  • bundle exec rspec spec/open_feature/sdk/provider/in_memory_provider_spec.rb — all pass
  • bundle exec rspec spec/open_feature/sdk/provider_compatibility_spec.rb — all pass
  • bundle exec standardrb — no offenses

🤖 Jose's AI agent

…vents

- Support callable (Proc/lambda) flag values that receive evaluation
  context, enabling dynamic flag resolution (Appendix A)
- Include Provider::EventEmitter in InMemoryProvider for event emission
- add_flag now emits PROVIDER_CONFIGURATION_CHANGED when attached to
  configuration
- Add update_flags method to replace entire flag set with event emission
- Remove TODO comments for completed features
- Update provider compatibility tests to reflect EventEmitter inclusion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jose Colella <jose.colella@gusto.com>
@josecolella josecolella requested a review from a team as a code owner March 5, 2026 16:39
@gemini-code-assist
Copy link

Summary of Changes

Hello, 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 significantly enhances the InMemoryProvider by introducing support for dynamic flag evaluation using context-aware callbacks and integrating event emission capabilities. These changes bring the InMemoryProvider closer to OpenFeature specification compliance, allowing for more flexible flag resolution and enabling external systems to react to configuration changes.

Highlights

  • Dynamic Flag Evaluation: Enabled dynamic flag evaluation by allowing callable (Proc/lambda) flag values that receive an evaluation context, aligning with OpenFeature Appendix A.
  • Event Emission Integration: Integrated Provider::EventEmitter into InMemoryProvider to support lifecycle event emission.
  • Configuration Change Events: Configured add_flag to emit a PROVIDER_CONFIGURATION_CHANGED event when the provider is attached to the configuration.
  • Bulk Flag Updates: Introduced an update_flags method for atomically replacing the entire flag set, accompanied by event emission.
  • Code Cleanup: Removed outdated TODO comments related to event emission and evaluation context.
  • Test Updates: Adjusted provider compatibility tests to reflect the new event emission capabilities of InMemoryProvider.
Changelog
  • lib/open_feature/sdk/provider/in_memory_provider.rb
    • Included Provider::EventEmitter module.
    • Removed a TODO comment regarding evaluation context support.
    • Added a call to emit_provider_changed within the add_flag method.
    • Implemented a new update_flags method to replace the entire flag set and emit a PROVIDER_CONFIGURATION_CHANGED event.
    • Modified fetch_value to execute callable flag values (Procs/lambdas) with the evaluation_context and return Reason::TARGETING_MATCH.
    • Introduced a private emit_provider_changed helper method to handle event emission conditionally.
  • spec/open_feature/sdk/provider/in_memory_provider_spec.rb
    • Added new test contexts for add_flag to verify PROVIDER_CONFIGURATION_CHANGED event emission when attached to configuration and no event emission when not attached.
    • Added a new describe block for #update_flags to test its functionality of replacing flags and emitting events.
    • Added a new describe block for "context callbacks (callable flag values)" to test Proc and lambda flag evaluation with evaluation_context and verify Reason::TARGETING_MATCH.
    • Added a test to confirm Reason::STATIC for non-callable flag values.
  • spec/open_feature/sdk/provider_compatibility_spec.rb
    • Updated the test description for event capabilities to reflect that InMemoryProvider now has event capabilities via EventEmitter.
    • Modified the EventEmitter check to directly use inmemory_provider instead of a separate event_capable_provider instance.
    • Removed the event_capable_provider let block as it is no longer needed.
Activity
  • The author completed a test plan, including rspec tests for in_memory_provider_spec.rb and provider_compatibility_spec.rb, and standardrb checks, all passing.
  • The PR is part of the spec compliance roadmap, specifically referencing Appendix A for context-aware evaluation, flag set updates, and event emission.
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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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

  1. 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.

Copy link

@gemini-code-assist gemini-code-assist bot left a 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 enhances the InMemoryProvider by adding support for context-aware dynamic flag evaluation and event emission for flag changes, aligning it with the OpenFeature specification. The changes are well-structured and include comprehensive tests. I've identified a potential issue with state mutation in the new update_flags method and suggested a minor improvement to test robustness. Overall, great work on implementing these features.

end

def update_flags(new_flags)
@flags = new_flags

Choose a reason for hiding this comment

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

high

The new_flags hash is assigned by reference, which could lead to unintended mutations of the provider's state if the original hash is modified after this call. This would happen without triggering change events, causing inconsistencies. Storing a shallow copy of the hash will prevent this.

          @flags = new_flags.dup

expect(config).to have_received(:dispatch_provider_event).with(
provider,
OpenFeature::SDK::ProviderEvent::PROVIDER_CONFIGURATION_CHANGED,
flags_changed: ["flag_a", "flag_b"]

Choose a reason for hiding this comment

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

medium

This test assertion depends on the order of keys in the flags_changed array, which can make the test brittle. Using RSpec's contain_exactly matcher will make the test more robust by ignoring the order of elements in the array.

          flags_changed: contain_exactly("flag_a", "flag_b")

josecolella and others added 2 commits March 5, 2026 08:51
- update_flags now stores a shallow copy to prevent external mutation
  without triggering change events
- Use contain_exactly for flags_changed assertion to avoid order
  dependency

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jose Colella <jose.colella@gusto.com>
@josecolella
Copy link
Collaborator Author

Both review comments addressed in ed2b2dc:

  1. .dup on update_flags — Fixed. @flags = new_flags.dup prevents external mutation without triggering change events.
  2. contain_exactly matcher — Fixed. Test no longer depends on hash key ordering.

🤖 Jose's AI agent

@josecolella josecolella merged commit 0a148f6 into main Mar 5, 2026
4 checks passed
@josecolella josecolella deleted the feat/in-memory-provider-context-events branch March 5, 2026 16:54
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.

1 participant