From c1ecdc51903b5a41169b2b3be2e4aad884936f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20D=C3=A1niel?= Date: Thu, 21 Nov 2024 16:52:00 +0100 Subject: [PATCH] Hooks update (#47) * ClientReady hooks rework * Fix autoPoll init in case of fetching * Update .gitignore * Added ktor-client dependency to nativeRestMain sourceSet. * ktlint fixes * Fixup tests * Update ConfigService.kt * Update Entry to handle cachedString * Code clean based on review * update jsMain dependency * Prepare 4.1.0 release * Deprecated original addOnClientReady method * Klint and test fix * testHooks test cover deprecated method --------- Co-authored-by: Peter Csajtai --- src/commonMain/kotlin/com/configcat/Hooks.kt | 30 ++++++++++++++++--- .../com/configcat/ConfigCatClientTests.kt | 16 +++++----- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/commonMain/kotlin/com/configcat/Hooks.kt b/src/commonMain/kotlin/com/configcat/Hooks.kt index ad447580..aba09edb 100644 --- a/src/commonMain/kotlin/com/configcat/Hooks.kt +++ b/src/commonMain/kotlin/com/configcat/Hooks.kt @@ -11,13 +11,31 @@ import kotlinx.atomicfu.locks.withLock */ public class Hooks { private val isClientReady = atomic(false) - private val clientCacheState = atomic(ClientCacheState.NO_FLAG_DATA) - private val onClientReady: MutableList<(ClientCacheState) -> Unit> = mutableListOf() + private val clientCacheState = atomic(ClientCacheState.NO_FLAG_DATA) + private val onClientReady: MutableList<() -> Unit> = mutableListOf() + private val onClientReadyWithState: MutableList<(ClientCacheState) -> Unit> = mutableListOf() private val onConfigChanged: MutableList<(Map) -> Unit> = mutableListOf() private val onFlagEvaluated: MutableList<(EvaluationDetails) -> Unit> = mutableListOf() private val onError: MutableList<(String) -> Unit> = mutableListOf() private val lock: ReentrantLock = reentrantLock() + /** + * This event is sent when the SDK reaches the ready state. + * If the SDK is configured with lazy load or manual polling it's considered ready right after instantiation. + * If it's using auto polling, the ready state is reached when the SDK has a valid config.json loaded into + * memory either from cache or from HTTP. If the config couldn't be loaded neither from cache nor + * from HTTP the `onClientReady` event fires when the auto polling's `maxInitWaitTimeInSeconds` is reached. + */ + @Deprecated( + message = "Use the new addOnClientReady(handler: (ClientCacheState) -> Unit) method.", + level = DeprecationLevel.WARNING, + ) + public fun addOnClientReady(handler: () -> Unit) { + lock.withLock { + onClientReady.add(handler) + } + } + /** * This event is sent when the SDK reaches the ready state. * If the SDK is configured with lazy load or manual polling it's considered ready right after instantiation. @@ -30,7 +48,7 @@ public class Hooks { if (isClientReady.value) { handler(clientCacheState.value) } else { - onClientReady.add(handler) + onClientReadyWithState.add(handler) } } } @@ -68,9 +86,12 @@ public class Hooks { lock.withLock { this.isClientReady.value = true this.clientCacheState.value = clientCacheState - for (method in onClientReady) { + for (method in onClientReadyWithState) { method(clientCacheState) } + for (method in onClientReady) { + method() + } } } @@ -101,6 +122,7 @@ public class Hooks { internal fun clear() { lock.withLock { onClientReady.clear() + onClientReadyWithState.clear() onConfigChanged.clear() onFlagEvaluated.clear() onError.clear() diff --git a/src/commonTest/kotlin/com/configcat/ConfigCatClientTests.kt b/src/commonTest/kotlin/com/configcat/ConfigCatClientTests.kt index 957012b3..fd4fca47 100644 --- a/src/commonTest/kotlin/com/configcat/ConfigCatClientTests.kt +++ b/src/commonTest/kotlin/com/configcat/ConfigCatClientTests.kt @@ -825,17 +825,17 @@ class ConfigCatClientTests { status = HttpStatusCode.OK, ) } - var ready = false + var ready: ClientCacheState? = null ConfigCatClient(TestUtils.randomSdkKey()) { httpEngine = mockEngine pollingMode = autoPoll { pollingInterval = 2.seconds } offline = true - hooks.addOnClientReady { ready = true } + hooks.addOnClientReady { clientCacheState-> ready = clientCacheState } } assertEquals(0, mockEngine.requestHistory.size) TestUtils.awaitUntil { - ready + ready != null } } @@ -917,14 +917,16 @@ class ConfigCatClientTests { } var error = "" var changed = false - var ready: ClientCacheState? = null + var ready = false + var readyWithClientState: ClientCacheState? = null val client = ConfigCatClient(TestUtils.randomSdkKey()) { httpEngine = mockEngine pollingMode = manualPoll() hooks.addOnConfigChanged { changed = true } - hooks.addOnClientReady { clientReadyState -> ready = clientReadyState } + hooks.addOnClientReady { clientReadyState -> readyWithClientState = clientReadyState } + hooks.addOnClientReady { -> ready = true} hooks.addOnError { err -> error = err } } @@ -942,8 +944,8 @@ class ConfigCatClientTests { ) assertTrue(changed) - - assertEquals(ClientCacheState.NO_FLAG_DATA, ready) + assertTrue(ready) + assertEquals(ClientCacheState.NO_FLAG_DATA, readyWithClientState) } @Test