Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 4 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.1.1-SNAPSHOT'
version = '3.2.0-SNAPSHOT'
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")

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

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

implementation 'com.github.zafarkhaja:java-semver:0.10.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
implementation 'org.ehcache:ehcache:3.10.8'
implementation 'org.slf4j:slf4j-api:2.0.13'
// Logback classic 1.3.x is compatible with java 8
implementation 'ch.qos.logback:logback-classic:1.3.14'
implementation 'org.jetbrains:annotations:13.0'

testImplementation 'cloud.eppo:sdk-common-jvm:3.2.0-SNAPSHOT:tests'
testImplementation 'cloud.eppo:sdk-common-jvm:3.5.0: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
45 changes: 39 additions & 6 deletions src/main/java/com/eppo/sdk/EppoClient.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
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.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -39,9 +44,11 @@ private EppoClient(
String host,
String sdkName,
String sdkVersion,
AssignmentLogger assignmentLogger,
BanditLogger banditLogger,
boolean isGracefulModel) {
@Nullable AssignmentLogger assignmentLogger,
@Nullable BanditLogger banditLogger,
boolean isGracefulMode,
@Nullable IAssignmentCache assignmentCache,
@Nullable IAssignmentCache banditAssignmentCache) {
super(
apiKey,
host,
Expand All @@ -50,10 +57,12 @@ private EppoClient(
assignmentLogger,
banditLogger,
null,
isGracefulModel,
isGracefulMode,
false,
true,
null);
null,
assignmentCache,
banditAssignmentCache);
}

/** Stops the client from polling Eppo for updated flag and bandit configurations */
Expand All @@ -73,6 +82,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 @@ -135,6 +150,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 @@ -153,7 +178,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