Skip to content

Commit

Permalink
Jitter-based cache expiration policy
Browse files Browse the repository at this point in the history
  • Loading branch information
VeryExtraordinaryUsername committed Nov 16, 2023
1 parent 5e4bb21 commit 87cc1fc
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ public USCustomLogicModuleCreator(USCustomLogicGppReaderFactory gppReaderFactory
JsonLogic jsonLogic,
Integer cacheTtl,
Integer cacheSize,
int refreshPeriod,
int jitter,
Metrics metrics) {

this.gppReaderFactory = Objects.requireNonNull(gppReaderFactory);
this.jsonLogic = Objects.requireNonNull(jsonLogic);
this.metrics = Objects.requireNonNull(metrics);

jsonLogicNodesCache = cacheTtl != null && cacheSize != null
? SettingsCache.createCache(cacheTtl, cacheSize, refreshPeriod)
? SettingsCache.createCache(cacheTtl, cacheSize, jitter)
: null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ public CachingApplicationSettings(ApplicationSettings delegate,
Metrics metrics,
int ttl,
int size,
int refreshPeriod) {
int jitter) {

if (ttl <= 0 || size <= 0) {
throw new IllegalArgumentException("ttl and size must be positive");
}
this.delegate = Objects.requireNonNull(delegate);
this.accountCache = SettingsCache.createCache(ttl, size, refreshPeriod);
this.accountToErrorCache = SettingsCache.createCache(ttl, size, refreshPeriod);
this.adServerPublisherToErrorCache = SettingsCache.createCache(ttl, size, refreshPeriod);
this.categoryConfigCache = SettingsCache.createCache(ttl, size, refreshPeriod);
this.accountCache = SettingsCache.createCache(ttl, size, jitter);
this.accountToErrorCache = SettingsCache.createCache(ttl, size, jitter);
this.adServerPublisherToErrorCache = SettingsCache.createCache(ttl, size, jitter);
this.categoryConfigCache = SettingsCache.createCache(ttl, size, jitter);
this.cache = Objects.requireNonNull(cache);
this.ampCache = Objects.requireNonNull(ampCache);
this.videoCache = Objects.requireNonNull(videoCache);
Expand Down
31 changes: 16 additions & 15 deletions src/main/java/org/prebid/server/settings/SettingsCache.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package org.prebid.server.settings;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.prebid.server.settings.model.StoredItem;

import javax.validation.ValidationException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
Expand All @@ -21,25 +22,25 @@ public class SettingsCache implements CacheNotificationListener {
private final Map<String, Set<StoredItem>> requestCache;
private final Map<String, Set<StoredItem>> impCache;

public SettingsCache(int ttl, int size, int refreshPeriod) {
public SettingsCache(int ttl, int size, int jitter) {
if (ttl <= 0 || size <= 0) {
throw new IllegalArgumentException("ttl and size must be positive");
}
requestCache = createCache(ttl, size, refreshPeriod);
impCache = createCache(ttl, size, refreshPeriod);
requestCache = createCache(ttl, size, jitter);
impCache = createCache(ttl, size, jitter);
}

public static <T> Map<String, T> createCache(int ttl, int size, int refreshPeriod) {
final Caffeine<Object, Object> caffeine = Caffeine.newBuilder().maximumSize(size);
if (refreshPeriod > 0 && refreshPeriod > ttl) {
throw new ValidationException("SettingsCache parameter \"refreshPeriod\" should be less than \"ttl\"");
}
if (refreshPeriod > 0) {
caffeine.refreshAfterWrite(ttl, TimeUnit.SECONDS).expireAfterWrite(ttl * 5L, TimeUnit.SECONDS);
} else {
caffeine.expireAfterWrite(ttl, TimeUnit.SECONDS);
}
return caffeine.<String, T>build().asMap();
public static <T> Map<String, T> createCache(int ttl, int size, int jitter) {
final Cache<String, T> cache = Caffeine.newBuilder()
.expireAfterWrite(ttl, TimeUnit.SECONDS)
.maximumSize(size)
.build();
cache.policy()
.expireAfterWrite()
.ifPresent(expiration -> expiration.setExpiresAfter(
jitter != 0 ? ttl + ThreadLocalRandom.current().nextLong(jitter * -1, jitter) : ttl,
TimeUnit.SECONDS));
return cache.asMap();
}

Map<String, Set<StoredItem>> getRequestCache() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ USCustomLogicModuleCreator usCustomLogicModuleCreator(
JsonLogic jsonLogic,
@Value("${settings.in-memory-cache.ttl-seconds:#{null}}") Integer ttlSeconds,
@Value("${settings.in-memory-cache.cache-size:#{null}}") Integer cacheSize,
@Value("${settings.in-memory-cache.refreshPeriod:0}") int refreshPeriod,
@Value("${settings.in-memory-cache.cache-size:0}") int jitter,
Metrics metrics) {

return new USCustomLogicModuleCreator(
gppReaderFactory, jsonLogic, ttlSeconds, cacheSize, refreshPeriod, metrics);
gppReaderFactory, jsonLogic, ttlSeconds, cacheSize, jitter, metrics);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ CachingApplicationSettings cachingApplicationSettings(
metrics,
cacheProperties.getTtlSeconds(),
cacheProperties.getCacheSize(),
cacheProperties.getRefreshPeriod());
cacheProperties.getJitter());
}
}

Expand All @@ -304,24 +304,21 @@ static class CacheConfiguration {
@Qualifier("settingsCache")
SettingsCache settingsCache(ApplicationSettingsCacheProperties cacheProperties) {
return new SettingsCache(
cacheProperties.getTtlSeconds(), cacheProperties.getCacheSize(), cacheProperties.getRefreshPeriod()
);
cacheProperties.getTtlSeconds(), cacheProperties.getCacheSize(), cacheProperties.getJitter());
}

@Bean
@Qualifier("ampSettingsCache")
SettingsCache ampSettingsCache(ApplicationSettingsCacheProperties cacheProperties) {
return new SettingsCache(
cacheProperties.getTtlSeconds(), cacheProperties.getCacheSize(), cacheProperties.getRefreshPeriod()
);
cacheProperties.getTtlSeconds(), cacheProperties.getCacheSize(), cacheProperties.getJitter());
}

@Bean
@Qualifier("videoSettingCache")
SettingsCache videoSettingCache(ApplicationSettingsCacheProperties cacheProperties) {
return new SettingsCache(
cacheProperties.getTtlSeconds(), cacheProperties.getCacheSize(), cacheProperties.getRefreshPeriod()
);
cacheProperties.getTtlSeconds(), cacheProperties.getCacheSize(), cacheProperties.getJitter());
}
}

Expand All @@ -339,7 +336,6 @@ private static class ApplicationSettingsCacheProperties {
@NotNull
@Min(1)
private Integer cacheSize;
@Min(0)
private int refreshPeriod;
private int jitter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ public void setUp() {
.willReturn(new USNationalGppReader(null));
given(jsonLogic.parse(any())).willReturn(JsonLogicBoolean.TRUE);

target = new USCustomLogicModuleCreator(
gppReaderFactory, jsonLogic, null, null, 0, metrics);
target = new USCustomLogicModuleCreator(gppReaderFactory, jsonLogic, null, null, 0, metrics);
}

@Test
Expand Down

0 comments on commit 87cc1fc

Please sign in to comment.