Skip to content

Commit b413cc4

Browse files
authored
Merge branch 'main' into renovate/org.mockito.kotlin-mockito-kotlin-5.x
2 parents 53dd164 + 458b564 commit b413cc4

24 files changed

+592
-648
lines changed

README.md

+18-44
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
<!-- x-hide-in-docs-end -->
1313
<!-- The 'github-badges' class is used in the docs -->
1414
<p align="center" class="github-badges">
15-
<a href="https://github.com/open-feature/spec/releases/tag/v0.6.0">
16-
<img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.6.0&color=yellow&style=for-the-badge" />
15+
<a href="https://github.com/open-feature/spec/releases/tag/v0.8.0">
16+
<img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.8.0&color=yellow&style=for-the-badge" />
1717
</a>
1818
<!-- x-release-please-start-version -->
1919
<a href="https://github.com/open-feature/kotlin-sdk/releases/tag/v0.3.3">
@@ -75,7 +75,7 @@ coroutineScope.launch(Dispatchers.IO) {
7575
|| [Tracking](#tracking) | Associate user actions with feature flag evaluations. |
7676
|| [Logging](#logging) | Integrate with popular logging packages. |
7777
|| [Named clients](#named-clients) | Utilize multiple providers in a single application. |
78-
| | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
78+
| | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
7979
|| [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
8080
| ⚠️ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |
8181

@@ -90,10 +90,21 @@ If the provider you're looking for hasn't been created yet, see the [develop a p
9090
Once you've added a provider as a dependency, it can be registered with OpenFeature like this:
9191

9292
```kotlin
93-
OpenFeatureAPI.setProviderAndWait(MyProvider())
93+
coroutineScope.launch(Dispatchers.IO) {
94+
OpenFeatureAPI.setProviderAndWait(MyProvider())
95+
}
9496
```
9597

96-
> Asynchronous API that doesn't wait is also available
98+
Asynchronous API that doesn't wait is also available. It's useful when you want to set a provider and continue with other tasks.
99+
100+
However, flag evaluations are only possible after the provider is Ready.
101+
102+
```kotlin
103+
OpenFeatureAPI.setProvider(MyProvider()) // can pass a dispatcher here
104+
// The provider initialization happens on a coroutine launched on the IO dispatcher.
105+
val status = OpenFeatureAPI.getStatus()
106+
// When status is Ready, flag evaluations can be made
107+
```
97108

98109

99110
### Targeting
@@ -164,35 +175,6 @@ Logging customization is not yet available in the Kotlin SDK.
164175

165176
Support for named clients is not yet available in the Kotlin SDK.
166177

167-
### Eventing
168-
169-
Events allow you to react to state changes in the provider or underlying flag management system, such as flag definition changes, provider readiness, or error conditions.
170-
Initialization events (`PROVIDER_READY` on success, `PROVIDER_ERROR` on failure) are dispatched for every provider.
171-
Some providers support additional events, such as `PROVIDER_CONFIGURATION_CHANGED`.
172-
173-
Please refer to the documentation of the provider you're using to see what events are supported.
174-
175-
Example usage:
176-
```kotlin
177-
viewModelScope.launch {
178-
OpenFeatureAPI.observe<OpenFeatureEvents.ProviderReady>().collect {
179-
println(">> ProviderReady event received")
180-
}
181-
}
182-
183-
viewModelScope.launch {
184-
OpenFeatureAPI.setProviderAndWait(
185-
ConfidenceFeatureProvider.create(
186-
applicationContext,
187-
clientSecret
188-
),
189-
Dispatchers.IO,
190-
myEvaluationContext
191-
)
192-
}
193-
```
194-
195-
<!-- (It's only possible to observe events from the global `OpenFeatureAPI`, until multiple providers are supported) -->
196178

197179
### Shutdown
198180

@@ -252,21 +234,13 @@ class NewProvider(override val hooks: List<Hook<*>>, override val metadata: Meta
252234
// resolve a string flag value
253235
}
254236

255-
override fun initialize(initialContext: EvaluationContext?) {
237+
override suspend fun initialize(initialContext: EvaluationContext?) {
256238
// add context-aware provider initialization
257239
}
258240

259-
override fun onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext) {
241+
override suspend fun onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext) {
260242
// add necessary changes on context change
261243
}
262-
263-
override fun observe(): Flow<OpenFeatureEvents> {
264-
// return a `Flow` of the Events
265-
}
266-
267-
override fun getProviderStatus(): OpenFeatureEvents {
268-
// return the event representative of the current Provider Status
269-
}
270244
}
271245
```
272246

android/src/main/java/dev/openfeature/sdk/FeatureProvider.kt

+23-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
package dev.openfeature.sdk
22

3-
import dev.openfeature.sdk.events.EventObserver
4-
import dev.openfeature.sdk.events.ProviderStatus
3+
import dev.openfeature.sdk.exceptions.OpenFeatureError
4+
import kotlin.jvm.Throws
55

6-
interface FeatureProvider : EventObserver, ProviderStatus {
6+
interface FeatureProvider {
77
val hooks: List<Hook<*>>
88
val metadata: ProviderMetadata
99

10-
// Called by OpenFeatureAPI whenever the new Provider is registered
11-
// This function should never throw
12-
fun initialize(initialContext: EvaluationContext?)
10+
/**
11+
* Called by OpenFeatureAPI whenever the new Provider is registered
12+
* This function should block until ready and throw exceptions if it fails to initialize
13+
* @param initialContext any initial context to be set before the provider is ready
14+
*/
15+
@Throws(OpenFeatureError::class)
16+
suspend fun initialize(initialContext: EvaluationContext?)
1317

14-
// Called when the lifecycle of the OpenFeatureClient is over
15-
// to release resources/threads
18+
/**
19+
* Called when the lifecycle of the OpenFeatureClient is over to release resources/threads
20+
*/
1621
fun shutdown()
1722

18-
// Called by OpenFeatureAPI whenever a new EvaluationContext is set by the application
19-
fun onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext)
23+
/**
24+
* Called by OpenFeatureAPI whenever a new EvaluationContext is set by the application
25+
* Perform blocking work here until the provider is ready again or throws an exception
26+
* @param oldContext The old EvaluationContext
27+
* @param newContext The new EvaluationContext
28+
* @throws OpenFeatureError if the provider cannot perform the task
29+
*/
30+
@Throws(OpenFeatureError::class)
31+
suspend fun onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext)
32+
2033
fun getBooleanEvaluation(
2134
key: String,
2235
defaultValue: Boolean,

android/src/main/java/dev/openfeature/sdk/NoOpProvider.kt

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
package dev.openfeature.sdk
22

3-
import dev.openfeature.sdk.events.OpenFeatureEvents
4-
import kotlinx.coroutines.flow.Flow
5-
import kotlinx.coroutines.flow.flowOf
6-
73
open class NoOpProvider(override val hooks: List<Hook<*>> = listOf()) : FeatureProvider {
84
override val metadata: ProviderMetadata = NoOpProviderMetadata("No-op provider")
9-
override fun initialize(initialContext: EvaluationContext?) {
5+
override suspend fun initialize(initialContext: EvaluationContext?) {
106
// no-op
117
}
128

139
override fun shutdown() {
1410
// no-op
1511
}
1612

17-
override fun onContextSet(
13+
override suspend fun onContextSet(
1814
oldContext: EvaluationContext?,
1915
newContext: EvaluationContext
2016
) {
@@ -61,9 +57,5 @@ open class NoOpProvider(override val hooks: List<Hook<*>> = listOf()) : FeatureP
6157
return ProviderEvaluation(defaultValue, "Passed in default", Reason.DEFAULT.toString())
6258
}
6359

64-
override fun observe(): Flow<OpenFeatureEvents> = flowOf()
65-
66-
override fun getProviderStatus(): OpenFeatureEvents = OpenFeatureEvents.ProviderReady
67-
6860
data class NoOpProviderMetadata(override val name: String?) : ProviderMetadata
6961
}

0 commit comments

Comments
 (0)