Skip to content

Commit d6d6538

Browse files
committed
refactor into FlagsStateManager
1 parent 2ffdd58 commit d6d6538

File tree

6 files changed

+227
-283
lines changed

6 files changed

+227
-283
lines changed

features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/FlagsStateListener.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,14 @@ import com.datadog.android.flags.model.FlagsClientState
1212
* Listener interface for receiving state change notifications from a [FlagsClient].
1313
*
1414
* Implementations of this interface can be registered with a [FlagsClient] to receive
15-
* callbacks whenever the client's state changes (e.g., from NOT_READY to READY, or
16-
* from READY to RECONCILING when the evaluation context changes).
15+
* callbacks whenever the client's state changes.
1716
*/
1817
interface FlagsStateListener {
1918
/**
2019
* Called when the state of the [FlagsClient] changes.
2120
*
22-
* @param newState The new state of the client.
23-
* @param error Optional error that caused the state change. This is typically provided
24-
* when transitioning to the [FlagsClientState.ERROR] state.
21+
* @param newState The new state of the client. If the state is [FlagsClientState.Error],
22+
* the error details are contained within the state object itself.
2523
*/
26-
fun onStateChanged(newState: FlagsClientState, error: Throwable? = null)
24+
fun onStateChanged(newState: FlagsClientState)
2725
}

features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/internal/FlagsStateChannel.kt

Lines changed: 0 additions & 90 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.flags.internal
8+
9+
import com.datadog.android.flags.FlagsStateListener
10+
import com.datadog.android.flags.model.FlagsClientState
11+
import com.datadog.android.internal.utils.DDCoreSubscription
12+
import java.util.concurrent.ExecutorService
13+
14+
/**
15+
* Manages state transitions and notifications for a [com.datadog.android.flags.FlagsClient].
16+
*
17+
* This class handles state change notifications to registered listeners. All notification
18+
* methods are thread-safe and guarantee ordered delivery to listeners by using a
19+
* single-threaded executor service.
20+
*
21+
* State updates trigger listener notifications asynchronously on the executor service.
22+
*
23+
* @param subscription the underlying subscription for managing listeners
24+
* @param executorService single-threaded executor for ordered state notification delivery
25+
*/
26+
internal class FlagsStateManager(
27+
private val subscription: DDCoreSubscription<FlagsStateListener>,
28+
private val executorService: ExecutorService
29+
) {
30+
/**
31+
* Updates the state and notifies all listeners.
32+
*
33+
* This method asynchronously notifies all registered listeners on the executor service,
34+
* ensuring ordered delivery.
35+
*
36+
* @param newState The new state to transition to.
37+
*/
38+
internal fun updateState(newState: FlagsClientState) {
39+
executorService.execute {
40+
subscription.notifyListeners {
41+
onStateChanged(newState)
42+
}
43+
}
44+
}
45+
46+
/**
47+
* Registers a listener to receive state change notifications.
48+
*
49+
* @param listener The listener to add.
50+
*/
51+
fun addListener(listener: FlagsStateListener) {
52+
subscription.addListener(listener)
53+
}
54+
55+
/**
56+
* Unregisters a previously registered listener.
57+
*
58+
* @param listener The listener to remove.
59+
*/
60+
fun removeListener(listener: FlagsStateListener) {
61+
subscription.removeListener(listener)
62+
}
63+
}

features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/model/FlagsClientState.kt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,37 @@ package com.datadog.android.flags.model
88

99
/**
1010
* Represents the current state of a [com.datadog.android.flags.FlagsClient].
11-
*
12-
* Note: A STALE state is not currently defined as there is no mechanism to determine
13-
* whether configuration is stale. This may be added in a future release.
1411
*/
15-
enum class FlagsClientState {
12+
sealed class FlagsClientState {
1613
/**
1714
* The client has been created but no evaluation context has been set.
1815
* No flags are available for evaluation in this state.
1916
*/
20-
NOT_READY,
17+
object NotReady : FlagsClientState()
2118

2219
/**
2320
* The client has successfully loaded flags and they are available for evaluation.
2421
* This is the normal operational state.
2522
*/
26-
READY,
23+
object Ready : FlagsClientState()
2724

2825
/**
2926
* The client is currently fetching new flags for a context change.
3027
* Cached flags may still be available for evaluation during this state.
3128
*/
32-
RECONCILING,
29+
object Reconciling : FlagsClientState()
30+
31+
/**
32+
* The client is currently stale.
33+
* Cached flags may still be available for evaluation during this state.
34+
*/
35+
object Stale : FlagsClientState()
3336

3437
/**
3538
* An unrecoverable error has occurred.
3639
* The client cannot provide flag evaluations in this state.
40+
*
41+
* @param error The error that caused the transition to this state, or null if unknown.
3742
*/
38-
ERROR
43+
data class Error(val error: Throwable? = null) : FlagsClientState()
3944
}

0 commit comments

Comments
 (0)