From 2b0d3fc4e8e9a3b44ba7076ae550afd61fcaadd2 Mon Sep 17 00:00:00 2001 From: Ty Potter Date: Mon, 24 Feb 2025 20:07:33 -0700 Subject: [PATCH 1/7] chore: use latest common --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 9030966..5f0d57e 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ java { } group = 'cloud.eppo' -version = '4.0.1-SNAPSHOT' +version = '4.1.0' ext.isReleaseVersion = !version.endsWith("SNAPSHOT") import org.apache.tools.ant.filters.ReplaceTokens @@ -30,7 +30,7 @@ repositories { } dependencies { - api 'cloud.eppo:sdk-common-jvm:3.6.0' + api 'cloud.eppo:sdk-common-jvm:3.8.0' implementation 'com.github.zafarkhaja:java-semver:0.10.2' implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2' From bc7293ba5e38b1ea8aa768d3ede9e4fcd93df35b Mon Sep 17 00:00:00 2001 From: Ty Potter Date: Mon, 24 Feb 2025 20:14:44 -0700 Subject: [PATCH 2/7] BREAKING CHANGE: EppoClient.stopPolling renamed to EppoClient.stopPollingSafe to address naming collision with new base method --- src/main/java/cloud/eppo/EppoClient.java | 5 +++-- src/test/java/cloud/eppo/EppoClientTest.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/cloud/eppo/EppoClient.java b/src/main/java/cloud/eppo/EppoClient.java index b16d323..be30db3 100644 --- a/src/main/java/cloud/eppo/EppoClient.java +++ b/src/main/java/cloud/eppo/EppoClient.java @@ -63,10 +63,11 @@ private EppoClient( } /** Stops the client from polling Eppo for updated flag and bandit configurations */ - public static void stopPolling() { + public static void stopPollingSafe() { if (pollTimer != null) { pollTimer.cancel(); } + } /** Builder pattern to initialize the EppoClient singleton */ @@ -186,7 +187,7 @@ public EppoClient buildAndInit() { banditAssignmentCache); // Stop any active polling - stopPolling(); + stopPollingSafe(); // Set up polling for experiment configurations pollTimer = new Timer(true); diff --git a/src/test/java/cloud/eppo/EppoClientTest.java b/src/test/java/cloud/eppo/EppoClientTest.java index db94f0e..7ffa4fc 100644 --- a/src/test/java/cloud/eppo/EppoClientTest.java +++ b/src/test/java/cloud/eppo/EppoClientTest.java @@ -91,7 +91,7 @@ private static String readConfig(String jsonToReturnFilePath) { @AfterEach public void cleanUp() { TestUtils.setBaseClientHttpClientOverrideField(null); - EppoClient.stopPolling(); + EppoClient.stopPollingSafe(); } @AfterAll @@ -232,7 +232,7 @@ public void testPolling() { // Now, the method should have been called twice verify(httpClientSpy, times(2)).get(anyString()); - EppoClient.stopPolling(); + EppoClient.stopPollingSafe(); sleepUninterruptedly(25); // No more calls since stopped From 8761de9f8f3fb11d2fc904313a2c52ec2c1179ba Mon Sep 17 00:00:00 2001 From: Ty Potter Date: Mon, 24 Feb 2025 20:14:51 -0700 Subject: [PATCH 3/7] major bump to v5.0.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5f0d57e..0ba942b 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ java { } group = 'cloud.eppo' -version = '4.1.0' +version = '5.0.0' ext.isReleaseVersion = !version.endsWith("SNAPSHOT") import org.apache.tools.ant.filters.ReplaceTokens From ffb1223040a91b34a3411868e64ba2421d1fee7d Mon Sep 17 00:00:00 2001 From: Ty Potter Date: Mon, 24 Feb 2025 20:21:03 -0700 Subject: [PATCH 4/7] move polling to base client --- src/main/java/cloud/eppo/EppoClient.java | 28 +++++++++--------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/main/java/cloud/eppo/EppoClient.java b/src/main/java/cloud/eppo/EppoClient.java index be30db3..8583148 100644 --- a/src/main/java/cloud/eppo/EppoClient.java +++ b/src/main/java/cloud/eppo/EppoClient.java @@ -5,7 +5,6 @@ import cloud.eppo.cache.LRUInMemoryAssignmentCache; import cloud.eppo.logging.AssignmentLogger; import cloud.eppo.logging.BanditLogger; -import java.util.Timer; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -26,7 +25,6 @@ public class EppoClient extends BaseEppoClient { private static final long DEFAULT_JITTER_INTERVAL_RATIO = 10; private static EppoClient instance; - private static Timer pollTimer; public static EppoClient getInstance() { if (instance == null) { @@ -64,10 +62,9 @@ private EppoClient( /** Stops the client from polling Eppo for updated flag and bandit configurations */ public static void stopPollingSafe() { - if (pollTimer != null) { - pollTimer.cancel(); + if (instance != null) { + instance.stopPolling(); } - } /** Builder pattern to initialize the EppoClient singleton */ @@ -164,6 +161,7 @@ public EppoClient buildAndInit() { String sdkVersion = appDetails.getVersion(); if (instance != null) { + instance.stopPolling(); if (forceReinitialize) { log.warn( "Eppo SDK is already initialized, reinitializing since forceReinitialize is true"); @@ -189,19 +187,13 @@ public EppoClient buildAndInit() { // Stop any active polling stopPollingSafe(); - // Set up polling for experiment configurations - pollTimer = new Timer(true); - FetchConfigurationsTask fetchConfigurationsTask = - new FetchConfigurationsTask( - () -> instance.loadConfiguration(), - pollTimer, - pollingIntervalMs, - pollingIntervalMs / DEFAULT_JITTER_INTERVAL_RATIO); - - // Kick off the first fetch - // Graceful mode is implicit here because `FetchConfigurationsTask` catches and logs errors - // without rethrowing. - fetchConfigurationsTask.run(); + // start polling, if enabled. + if (pollingIntervalMs > 0) { + instance.startPolling(pollingIntervalMs, pollingIntervalMs / DEFAULT_JITTER_INTERVAL_RATIO); + } + + // Fetch configuration + instance.loadConfiguration(); return instance; } From 1957102505b5b987ffac172f1899356c44552601 Mon Sep 17 00:00:00 2001 From: Ty Potter Date: Mon, 24 Feb 2025 20:32:52 -0700 Subject: [PATCH 5/7] chore: Real Breaking Change: Removed EppoClient.stopPolling altogether --- src/main/java/cloud/eppo/EppoClient.java | 15 +++------------ src/test/java/cloud/eppo/EppoClientTest.java | 8 ++++++-- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/java/cloud/eppo/EppoClient.java b/src/main/java/cloud/eppo/EppoClient.java index 8583148..2640925 100644 --- a/src/main/java/cloud/eppo/EppoClient.java +++ b/src/main/java/cloud/eppo/EppoClient.java @@ -60,13 +60,6 @@ private EppoClient( banditAssignmentCache); } - /** Stops the client from polling Eppo for updated flag and bandit configurations */ - public static void stopPollingSafe() { - if (instance != null) { - instance.stopPolling(); - } - } - /** Builder pattern to initialize the EppoClient singleton */ public static class Builder { private String apiKey; @@ -161,6 +154,7 @@ public EppoClient buildAndInit() { String sdkVersion = appDetails.getVersion(); if (instance != null) { + // Stop any active polling. instance.stopPolling(); if (forceReinitialize) { log.warn( @@ -184,17 +178,14 @@ public EppoClient buildAndInit() { assignmentCache, banditAssignmentCache); - // Stop any active polling - stopPollingSafe(); + // Fetch first configuration + instance.loadConfiguration(); // start polling, if enabled. if (pollingIntervalMs > 0) { instance.startPolling(pollingIntervalMs, pollingIntervalMs / DEFAULT_JITTER_INTERVAL_RATIO); } - // Fetch configuration - instance.loadConfiguration(); - return instance; } } diff --git a/src/test/java/cloud/eppo/EppoClientTest.java b/src/test/java/cloud/eppo/EppoClientTest.java index 7ffa4fc..d4d35f1 100644 --- a/src/test/java/cloud/eppo/EppoClientTest.java +++ b/src/test/java/cloud/eppo/EppoClientTest.java @@ -91,7 +91,11 @@ private static String readConfig(String jsonToReturnFilePath) { @AfterEach public void cleanUp() { TestUtils.setBaseClientHttpClientOverrideField(null); - EppoClient.stopPollingSafe(); + try { + EppoClient.getInstance().stopPolling(); + } catch (IllegalStateException ex) { + // pass: Indicates that the singleton Eppo Client has not yet been initialized. + } } @AfterAll @@ -232,7 +236,7 @@ public void testPolling() { // Now, the method should have been called twice verify(httpClientSpy, times(2)).get(anyString()); - EppoClient.stopPollingSafe(); + EppoClient.getInstance().stopPolling(); sleepUninterruptedly(25); // No more calls since stopped From 8a4a801d0a8d73d5ef699837f964667ec5eea4dd Mon Sep 17 00:00:00 2001 From: Ty Potter Date: Mon, 24 Feb 2025 20:36:33 -0700 Subject: [PATCH 6/7] add a test for getConfiguration --- src/test/java/cloud/eppo/EppoClientTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/cloud/eppo/EppoClientTest.java b/src/test/java/cloud/eppo/EppoClientTest.java index d4d35f1..cb971fb 100644 --- a/src/test/java/cloud/eppo/EppoClientTest.java +++ b/src/test/java/cloud/eppo/EppoClientTest.java @@ -11,6 +11,7 @@ import cloud.eppo.api.Attributes; import cloud.eppo.api.BanditActions; import cloud.eppo.api.BanditResult; +import cloud.eppo.api.Configuration; import cloud.eppo.helpers.AssignmentTestCase; import cloud.eppo.helpers.BanditTestCase; import cloud.eppo.helpers.TestUtils; @@ -18,6 +19,7 @@ import cloud.eppo.logging.AssignmentLogger; import cloud.eppo.logging.BanditAssignment; import cloud.eppo.logging.BanditLogger; +import cloud.eppo.ufc.dto.VariationType; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; @@ -261,6 +263,15 @@ public void testClientMakesDefaultAssignmentsAfterFailingToInitialize() { } } + @Test + public void testGetConfiguration() { + EppoClient eppoClient = initClient(DUMMY_FLAG_API_KEY); + Configuration configuration = eppoClient.getConfiguration(); + assertNotNull(configuration); + assertNotNull(configuration.getFlag("numeric_flag")); + assertEquals(VariationType.NUMERIC, configuration.getFlagType("numeric_flag")); + } + public static void mockHttpError() { // Create a mock instance of EppoHttpClient EppoHttpClient mockHttpClient = mock(EppoHttpClient.class); From c13cb4a67d90199617fb1d73c1992e70b4baf99d Mon Sep 17 00:00:00 2001 From: Ty Potter Date: Tue, 25 Feb 2025 08:13:00 -0700 Subject: [PATCH 7/7] chore: mark snapshot version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0ba942b..d614b32 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ java { } group = 'cloud.eppo' -version = '5.0.0' +version = '5.0.0-SNAPSHOT' ext.isReleaseVersion = !version.endsWith("SNAPSHOT") import org.apache.tools.ant.filters.ReplaceTokens