Skip to content
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

feat!: Make the eventing provider specific instead of being singleton #75

Merged
merged 2 commits into from
Dec 18, 2023

Conversation

vahidlazio
Copy link
Collaborator

@vahidlazio vahidlazio commented Dec 7, 2023

This PR

  • Make the eventing provider specific instead of being singleton

@vahidlazio vahidlazio changed the title [WIP] Make the eventing provider specific instead of being singletone [feat] Make the eventing provider specific instead of being singletone Dec 7, 2023
@vahidlazio vahidlazio changed the title [feat] Make the eventing provider specific instead of being singletone feat(refactor) Make the eventing provider specific instead of being singletone Dec 7, 2023
@vahidlazio vahidlazio self-assigned this Dec 7, 2023
@vahidlazio vahidlazio force-pushed the make-provider-eventing-provider-specific branch 2 times, most recently from e828a5a to 69379d2 Compare December 7, 2023 12:04
@vahidlazio vahidlazio changed the title feat(refactor) Make the eventing provider specific instead of being singletone feat: Make the eventing provider specific instead of being singletone Dec 7, 2023
Copy link
Contributor

@fabriziodemaria fabriziodemaria left a comment

Choose a reason for hiding this comment

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

Overall, I think there is an opportunity to take inspiration from the Java SDK setup (which should also adhere very well to the Specs): https://github.com/open-feature/java-sdk/tree/main

@nicklasl nicklasl changed the title feat: Make the eventing provider specific instead of being singletone feat: Make the eventing provider specific instead of being singleton Dec 7, 2023
@vahidlazio vahidlazio force-pushed the make-provider-eventing-provider-specific branch 2 times, most recently from 6292faa to 2d3d26c Compare December 14, 2023 19:39
@vahidlazio vahidlazio marked this pull request as ready for review December 14, 2023 19:43
dispatcher: CoroutineDispatcher = Dispatchers.IO
) {
val provider = getProvider()
requireNotNull(provider)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove this too. I guess this function would just return right away if no provider is set?

Copy link
Member

Choose a reason for hiding this comment

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

Hm... If no provider is set then getProvider() returns null and I assume requireNotNull will throw an exception. This is not great IMO.

Ideally this suspending function would just hang until a provider is set on OpenFeatureAPI and become ready. However I don't know how to solve that. Ideas?

Copy link
Member

Choose a reason for hiding this comment

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

Is it completely crazy to setup a flow where we continously poll getProvider() until one becomes available?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i thought about polling .. but isn't it too much maybe?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

we have 5 options :
1- not have this function at all.
2- never return from this suspending if no provider set (bad because you won't know why you don't get out of the await function)
3- exception with correct message so you know you ask for this function early
4- poll until provider is set
5- return if provider is null (bad because returning implies the provider is ready which is not in this case)

IMO, we need to choose between option 4 or 3. I chose the option 3 but if that's violating the not throwing exception rule. I can try the polling thing.

Copy link
Member

Choose a reason for hiding this comment

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

I may be missing some of the context here but would it be possible to return he no-op provider?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@beeme1mr we updated the extension to be like following instead of waiting for provider in a different line and we are adding the setProviderAndAwaitReady.

suspend fun OpenFeatureAPI.setProviderAndAwaitReady(
    provider: FeatureProvider,
    dispatcher: CoroutineDispatcher
) {
    OpenFeatureAPI.setProvider(provider)
    provider.awaitReady(dispatcher)
}

}

interface EventObserver {
fun <T : OpenFeatureEvents> observe(kClass: KClass<T>): Flow<T>
interface ProviderStatus {
Copy link
Member

Choose a reason for hiding this comment

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

nit: I would expect an interface such as this to have a getStatus(): Status function.

@vahidlazio vahidlazio force-pushed the make-provider-eventing-provider-specific branch 2 times, most recently from 6cdcbdf to 8a4414e Compare December 15, 2023 14:36
@vahidlazio vahidlazio force-pushed the make-provider-eventing-provider-specific branch from 8a4414e to 5a99cc3 Compare December 15, 2023 14:37
@vahidlazio vahidlazio force-pushed the make-provider-eventing-provider-specific branch from 5a99cc3 to cd34e5e Compare December 15, 2023 15:49
@vahidlazio vahidlazio requested a review from beeme1mr December 15, 2023 15:50
import dev.openfeature.sdk.events.OpenFeatureEvents
import dev.openfeature.sdk.events.observe
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine

Copy link
Member

@nicklasl nicklasl Dec 18, 2023

Choose a reason for hiding this comment

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

Need to put some proper effort in documenting the API's in this file but I think this can go in a separate PR.

import dev.openfeature.sdk.events.OpenFeatureEvents
import kotlinx.coroutines.CoroutineDispatcher

class TestFeatureProvider(
Copy link
Member

Choose a reason for hiding this comment

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

Can this be the in-memory provider? We started adding those in to other SDKs. It can be used in tests or for basic use cases.

Copy link
Member

Choose a reason for hiding this comment

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

In most SDKs there's a testing provider (or a few) that have more testing features related to testing the SDK itself (such as throwing on init to test init logic, etc). That seems more like what this is.

The in-memory provider is mostly for outsiders to test things. I think that's a separate issue.

import dev.openfeature.sdk.exceptions.OpenFeatureError.FlagNotFoundError
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
Copy link
Member

Choose a reason for hiding this comment

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

This is imported twice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

will fix in the next PR.

Copy link
Member

@toddbaert toddbaert left a comment

Choose a reason for hiding this comment

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

I'm not much of a Kotlin dev, so I could be missing something, but this looks right to me.

I think this will make implementing named providers more simple.

@vahidlazio vahidlazio merged commit 321f8be into main Dec 18, 2023
3 checks passed
@vahidlazio vahidlazio changed the title feat: Make the eventing provider specific instead of being singleton feat!: Make the eventing provider specific instead of being singleton Dec 19, 2023
@fabriziodemaria fabriziodemaria deleted the make-provider-eventing-provider-specific branch January 31, 2024 15:24
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.

5 participants