Skip to content

Conversation

PenguinDan
Copy link

@PenguinDan PenguinDan commented Aug 20, 2025

This PR

Multi Provider implementation according to the specifications outlined in https://openfeature.dev/specification/appendix-a/#multi-provider

  • Does not implement support for hooks for the moment

Related Issues

Fixes #149

Notes

Work that still needs to be done

  • Need to go through the specifications one more time to make sure the implementation aligns with it

Follow-up Tasks

  1. Add a logging tool?
  2. Event Type enhancements Missing OpenFeature Events types. #107
  3. Documentation updates

How to test

Updated the sample application to utilize a multi provider

@PenguinDan PenguinDan changed the title Multi provider impl feat: Multi provider impl Aug 20, 2025
return eval
}
// Continue to next provider if error is FLAG_NOT_FOUND
} catch (_: OpenFeatureError.FlagNotFoundError) {
Copy link
Author

Choose a reason for hiding this comment

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

No logging tool, just swallowing for the moment

// Event precedence (highest to lowest priority) - based on the specifications
private val eventPrecedence = mapOf(
OpenFeatureProviderEvents.ProviderError::class to 4, // FATAL/ERROR
OpenFeatureProviderEvents.ProviderNotReady::class to 3, // NOT READY, Deprecated but still supporting
Copy link
Author

Choose a reason for hiding this comment

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

Do we want to add back support for this Event?

According to the documentation https://openfeature.dev/specification/appendix-a/#status-and-event-handling

Initially the status is NOT_READY

The only way to represent the NOT_READY state is by setting the initial value of the eventFlow to an Error, where, it would probably be smarter not to represent the initial state as being in "error"?

Copy link
Member

Choose a reason for hiding this comment

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

I think we should look into this. I've thought about it recently as well and for me NOT_READY is a valid state. I don't remember why it was deprecated.

Copy link
Author

Choose a reason for hiding this comment

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

@nicklasl Not finding much details on why NOT_READY has been deprecated. I just see this PR #124 that re-introduces the ProviderNotReady object but deprecated.

I think it make sense to undeprecate this to support initializing providers with ProviderNotReady

Copy link
Author

@PenguinDan PenguinDan Aug 21, 2025

Choose a reason for hiding this comment

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

Ah okay, was a bit confusing but Events rightfully don't have a NotReady state: https://openfeature.dev/specification/types#provider-events

The documentation makes it confusing by mentioning both Events and Statuses in the section (i.e ConfigurationChangedEvent)

Still trying to wrap my head around the specifications outlined here and what they actually mean lol: https://openfeature.dev/specification/appendix-a#multi-provider-status

Copy link
Author

Choose a reason for hiding this comment

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

Okay, so looks like what we need to do is

  1. Listen to all events of the Providers and map those to STATUS emitted by the MultiProvider
  2. Listen to all events of the Providers and re-emit the event from our own observe() function if that particular event updates the STATUS of our MultiProvider. (Caveat here being that we always re-emit Configuration changed..)

Copy link
Author

Choose a reason for hiding this comment

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

Okay, 4fa33eb this should now align with the specs.

Definitely need to do another round of double checking things

* See: https://openfeature.dev/specification/appendix-a/#metadata
*/
val originalMetadata: Map<String, ProviderMetadata>
get() = emptyMap()
Copy link
Member

Choose a reason for hiding this comment

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

nice with defaults to not make it breaking 👍

@PenguinDan PenguinDan marked this pull request as ready for review August 22, 2025 17:11
Copy link
Contributor

@bencehornak bencehornak left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the contributions, @PenguinDan, they look very promising! Nothing serious, only minor findings from my side!

@PenguinDan PenguinDan requested a review from bencehornak August 26, 2025 17:50
Signed-off-by: penguindan <[email protected]>
Copy link
Contributor

@bencehornak bencehornak left a comment

Choose a reason for hiding this comment

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

Thanks for the updates, going to the right direction!

PenguinDan and others added 2 commits August 30, 2025 16:05
…ltiprovider/FirstSuccessfulStrategy.kt

Co-authored-by: Bence Hornák <[email protected]>
Signed-off-by: Daniel Kim <[email protected]>
@PenguinDan PenguinDan requested a review from bencehornak August 30, 2025 23:26
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.

[FEATURE] Implement Multiprovider
4 participants