Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ java {
}

group = 'cloud.eppo'
version = '3.0.2-SNAPSHOT'
version = '3.1.0'
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")

import org.apache.tools.ant.filters.ReplaceTokens
Expand All @@ -31,7 +31,7 @@ repositories {

dependencies {
// Re-export classes and interfaces that will be used upstream
api 'cloud.eppo:sdk-common-jvm:3.0.2'
api 'cloud.eppo:sdk-common-jvm:3.5.0-SNAPSHOT'
Copy link
Contributor

Choose a reason for hiding this comment

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

you probably don't need this to be a snapshot version anymore since v3.5.0 has been released, right? same below line 43

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

👍


implementation 'com.github.zafarkhaja:java-semver:0.10.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
Expand All @@ -40,7 +40,7 @@ dependencies {
// Logback classic 1.3.x is compatible with java 8
implementation 'ch.qos.logback:logback-classic:1.3.14'

testImplementation 'cloud.eppo:sdk-common-jvm:3.0.0-SNAPSHOT:tests'
testImplementation 'cloud.eppo:sdk-common-jvm:3.2.0-SNAPSHOT:tests'
testImplementation platform('org.junit:junit-bom:5.10.2')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'com.github.tomakehurst:wiremock-jre8:2.35.2'
Expand Down
48 changes: 45 additions & 3 deletions src/main/java/com/eppo/sdk/EppoClient.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.eppo.sdk;

import cloud.eppo.BaseEppoClient;
import cloud.eppo.api.IAssignmentCache;
import cloud.eppo.cache.ExpiringInMemoryAssignmentCache;
import cloud.eppo.cache.LRUInMemoryAssignmentCache;
import cloud.eppo.logging.AssignmentLogger;
import cloud.eppo.logging.BanditLogger;
import com.eppo.sdk.helpers.AppDetails;
import com.eppo.sdk.helpers.FetchConfigurationsTask;
import java.util.Timer;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -41,9 +45,23 @@ private EppoClient(
String sdkVersion,
AssignmentLogger assignmentLogger,
BanditLogger banditLogger,
boolean isGracefulModel) {
boolean isGracefulModel,
IAssignmentCache assignmentCache,
IAssignmentCache banditAssignmentCache) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Add @Nullable or @NonNull annotations as needed

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

super(
apiKey, host, sdkName, sdkVersion, assignmentLogger, banditLogger, isGracefulModel, false);
apiKey,
host,
sdkName,
sdkVersion,
assignmentLogger,
banditLogger,
null,
isGracefulModel,
false,
true,
null,
assignmentCache,
banditAssignmentCache);
}

/** Stops the client from polling Eppo for updated flag and bandit configurations */
Expand All @@ -63,6 +81,12 @@ public static class Builder {
private long pollingIntervalMs = DEFAULT_POLLING_INTERVAL_MS;
private String host = DEFAULT_HOST;

// Assignment and bandit caching on by default. To disable, call
// `builder.assignmentCache(null).banditAssignmentCache(null);`
private IAssignmentCache assignmentCache = new LRUInMemoryAssignmentCache(100);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

How much of this configuration should we surface to devs?
The cache size or ttl? or the IAssignmentCache. Or should we surface as a set of caching options on the builder, similar to JS (ex: withLruAssignmentCaching(100), withExpiringCache(10, MINUTES) etc)

Copy link
Contributor

Choose a reason for hiding this comment

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

I like the option of providing convenience methods like withLruAssignmentCaching and withExpiringCache, however we should also allow users to bring their own implementation of IAssignmentCache, so we also need a withAssignmentCache that takes the interface. EDIT: Looks like you already added it below, so we're good on that one

private IAssignmentCache banditAssignmentCache =
new ExpiringInMemoryAssignmentCache(10, TimeUnit.MINUTES);

/** Sets the API Key--created within the eppo application--to use. This is required. */
public Builder apiKey(String apiKey) {
this.apiKey = apiKey;
Expand Down Expand Up @@ -125,6 +149,16 @@ public Builder host(String host) {
return this;
}

public Builder assignmentCache(IAssignmentCache assignmentCache) {
this.assignmentCache = assignmentCache;
return this;
}

public Builder banditAssignmentCache(IAssignmentCache banditAssignmentCache) {
this.banditAssignmentCache = banditAssignmentCache;
return this;
}

public EppoClient buildAndInit() {
AppDetails appDetails = AppDetails.getInstance();
String sdkName = appDetails.getName();
Expand All @@ -143,7 +177,15 @@ public EppoClient buildAndInit() {

instance =
new EppoClient(
apiKey, sdkName, sdkVersion, host, assignmentLogger, banditLogger, isGracefulMode);
apiKey,
sdkName,
sdkVersion,
host,
assignmentLogger,
banditLogger,
isGracefulMode,
assignmentCache,
banditAssignmentCache);

// Stop any active polling
stopPolling();
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/eppo/sdk/EppoClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ private void uninitClient() {
private void initBuggyClient() {
try {
EppoClient eppoClient = initClient(DUMMY_FLAG_API_KEY);
Field configurationStoreField = BaseEppoClient.class.getDeclaredField("requestor");
Field configurationStoreField = BaseEppoClient.class.getDeclaredField("configurationStore");
configurationStoreField.setAccessible(true);
configurationStoreField.set(eppoClient, null);
} catch (NoSuchFieldException | IllegalAccessException e) {
Expand Down