Skip to content
This repository has been archived by the owner on Sep 13, 2023. It is now read-only.

Add Events and async client #32

Merged
merged 6 commits into from
Jul 24, 2023
Merged

Add Events and async client #32

merged 6 commits into from
Jul 24, 2023

Conversation

vahidlazio
Copy link
Contributor

@vahidlazio vahidlazio commented Jul 19, 2023

  • Add basics for adding the events
  • Add extension to convert the client to the async client.

To do some actions after provider is ready:

CoroutineScope(Dispatchers.IO).launch {
        awaitProviderReady()
        // now provider is ready, read the properties
    }

The usage will be something like:

openFeatureClient
.toAsync()
.observeStringValue(key, default)
.collect { 
// do something with boolean
}

in the compose world will be:

val myStringProperty = openFeatureClient
.toAsync()
.observeStringValue(key, default)
.collectAsState()

we can update the implementation to limit the value emissions only for when the provider is initialised and ready to not emit the default value if the provider is not ready.

@vahidlazio vahidlazio changed the title add basics for adding the events, add extension to convert the client… Add Events and async client Jul 19, 2023
@vahidlazio vahidlazio force-pushed the adding-minimal-event branch 7 times, most recently from b909c14 to 35f4e8c Compare July 20, 2023 13:21
@vahidlazio vahidlazio force-pushed the adding-minimal-event branch 2 times, most recently from 97af885 to 027939d Compare July 21, 2023 11:50
Copy link
Member

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

Still unfamiliar with the details of Flow, but added some generic comments

internal class AsyncClientImpl(
private val client: OpenFeatureClient
) : AsyncClient {
private fun <T> observeEvents(callback: () -> T) = observeProviderReady()
Copy link
Member

Choose a reason for hiding this comment

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

Can we have a "observeProviderState" that listens to any Provider State event?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we have 2 functions one observeProviderReady and another one a suspending function awaitProviderReady(). added to the description of the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i removed the secondary way and now we have one way as helper functions to listen for providerReady

CoroutineScope(Dispatchers.IO).launch {
        awaitProviderReady()
        // now provider is ready, read the properties
    }

@@ -0,0 +1,9 @@
package dev.openfeature.sdk.events

sealed class OpenFeatureEvents {
Copy link
Member

Choose a reason for hiding this comment

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

Should we name this to something "state" specific, e.g. ProviderStateEvents?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i would argue this can be used to any sort of event from the provider and IMO it's not always about the provider state.

return AsyncClientImpl(this)
}

fun observeProviderReady() = EventHandler.eventsObserver()
Copy link
Member

Choose a reason for hiding this comment

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

Similar comment above: let's extend this to support any ProviderStateEvent type?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is just a helper function for provider ready. the design already allows listening for all the events like:

EventHandler.eventsObserver()
.observe<OpenFeatureEvents>()
.collect {
// do something with the event
}

@@ -5,10 +5,14 @@ interface FeatureProvider {
val metadata: ProviderMetadata

// Called by OpenFeatureAPI whenever the new Provider is registered
suspend fun initialize(initialContext: EvaluationContext?)
fun initialize(initialContext: EvaluationContext?)
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should keep "suspend" in the interface towards the Provider, and only remove "suspend" from the OpenFeature user-facing API setProvider

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think it makes sense that now we have the shutdown function we move the responsibility of having scopes and suspending in the provider side. but we can further discuss this.

Comment on lines +37 to +38
is OpenFeatureEvents.ProviderReady -> isProviderReady.value = true
is OpenFeatureEvents.ProviderShutDown -> {
Copy link
Member

@fabriziodemaria fabriziodemaria Jul 21, 2023

Choose a reason for hiding this comment

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

I wonder is the provider is not ready after ProviderConfigurationChanged as well, as I think that's when a new EvaluationContext is set and the Provider starts fetching the new values from backend

Copy link
Contributor Author

@vahidlazio vahidlazio Jul 21, 2023

Choose a reason for hiding this comment

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

like ShutDownCompleted? i believe the signal of shutdown is coming from the Provider and it's signaling that the provider is shut down.

@fabriziodemaria
Copy link
Member

fabriziodemaria commented Jul 21, 2023

Would be great to curate the PR description a bit more, since this is probably the place where all reviews will happen.
A few ideas:

  • Can we elaborate more on the toAsync() function? Is this necessary if we expect users to always use our async APIs anyway (do we expect that?))
  • Perhaps adding a few more code examples on how to wait for ProviderReady and just get a flag value after that (without observing the flag value via "Flow")

@vahidlazio vahidlazio marked this pull request as ready for review July 21, 2023 13:40
@vahidlazio vahidlazio merged commit fd8c5eb into main Jul 24, 2023
1 check passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants