Skip to content

Commit

Permalink
refactor: Changed duration data type for config
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien Ruaux committed Feb 25, 2023
1 parent 41f6bd5 commit 7b4c354
Show file tree
Hide file tree
Showing 24 changed files with 513 additions and 353 deletions.
9 changes: 3 additions & 6 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,13 @@ Here is the default rule configuration:
"tablesAny": null,
"tablesAll": null,
"regex": null,
"ttl": 3600
"ttl": "1h"
}
]
}
----

This default configuration contains a single passthrough rule where all SQL query results will be assigned a TTL of 3600 seconds.
This default configuration contains a single passthrough rule where all SQL query results will be assigned a TTL of 1 hour.

Rules are processed in order and consist of *criteria* (conditions) and *actions* (results).
Only the first rule with matching criteria will be considered, and its action applied.
Expand All @@ -358,10 +358,7 @@ Only the first rule with matching criteria will be considered, and its action ap

==== Action

`ttl`:: Sets the time-to-live (in seconds) for the corresponding cache entry (default: `3600`).
[horizontal]
`0`:::: No caching
`-1`:::: No expiration
`ttl`:: Sets the time-to-live for the corresponding cache entry (default: `1h`). Use `0s` to disable caching.

==== Examples

Expand Down
1 change: 0 additions & 1 deletion core/redis-smart-cache-jdbc/redis-smart-cache-jdbc.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ dependencies {
implementation 'org.apache.commons:commons-pool2'
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-properties'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
implementation group: 'com.redis', name: 'micrometer-registry-redistimeseries', version: micrometerRedisVersion
implementation group: 'io.trino', name: 'trino-parser', version: trinoVersion
implementation group: 'io.airlift', name: 'units', version: airliftVersion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -17,15 +16,10 @@

import javax.sql.rowset.RowSetFactory;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.dataformat.javaprop.JavaPropsMapper;
import com.fasterxml.jackson.dataformat.javaprop.JavaPropsSchema;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.redis.lettucemod.api.StatefulRedisModulesConnection;
import com.redis.lettucemod.util.ClientBuilder;
import com.redis.lettucemod.util.RedisModulesUtils;
import com.redis.lettucemod.util.RedisURIBuilder;
Expand All @@ -35,11 +29,12 @@
import com.redis.smartcache.core.Config.DriverConfig;
import com.redis.smartcache.core.Config.RedisConfig;
import com.redis.smartcache.core.Config.RulesetConfig;
import com.redis.smartcache.core.ConfigManager;
import com.redis.smartcache.core.QueryRuleSession;
import com.redis.smartcache.core.RedisResultSetCache;
import com.redis.smartcache.core.ResultSetCache;
import com.redis.smartcache.core.codec.ResultSetCodec;
import com.redis.smartcache.core.config.ConfigManager;
import com.redis.smartcache.core.config.ObjectMappers;
import com.redis.smartcache.jdbc.SmartConnection;
import com.redis.smartcache.jdbc.rowset.CachedRowSetFactory;

Expand Down Expand Up @@ -76,10 +71,8 @@ public class Driver implements java.sql.Driver {
private static final String JDBC_URL_REGEX = "jdbc\\:(rediss?(\\-(socket|sentinel))?\\:\\/\\/.*)";
private static final Pattern JDBC_URL_PATTERN = Pattern.compile(JDBC_URL_REGEX);
private static final JavaPropsSchema PROPS_SCHEMA = JavaPropsSchema.emptySchema().withPrefix(PROPERTY_PREFIX);
private static final JavaPropsMapper PROPS_MAPPER = JavaPropsMapper.builder()
.propertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE).serializationInclusion(Include.NON_NULL)
.addModule(new JavaTimeModule()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS).build();
private static final JavaPropsMapper PROPS_MAPPER = ObjectMappers.javaProps();
private static final JsonMapper JSON_MAPPER = ObjectMappers.json();

private static final RowSetFactory rowSetFactory = new CachedRowSetFactory();
private static final Map<String, java.sql.Driver> drivers = new HashMap<>();
Expand Down Expand Up @@ -137,10 +130,18 @@ public SmartConnection connect(String url, Properties info) throws SQLException
return makeConnection(config, info);
}

private static SmartConnection makeConnection(Config conf, Properties info) throws SQLException {
private SmartConnection makeConnection(Config conf, Properties info) throws SQLException {
Connection backend = backendConnection(conf.getDriver(), info);
AbstractRedisClient client = clients.computeIfAbsent(conf.getRedis(), Driver::redisClient);
QueryRuleSession session = sessions.computeIfAbsent(conf, c -> ruleSession(c, client));
QueryRuleSession session = sessions.computeIfAbsent(conf, this::ruleSession);
ConfigManager<RulesetConfig> configManager = configManagers.computeIfAbsent(conf,
config -> new ConfigManager<>(JSON_MAPPER, RedisModulesUtils.connection(client), config.key("config"),
config.getRuleset(), Duration.ofMillis(config.getConfigStep().toMillis())));
try {
configManager.start();
} catch (JsonProcessingException e) {
logger.log(Level.WARNING, "Could not initialize config manager", e);
}
ResultSetCodec codec = new ResultSetCodec(rowSetFactory, Math.toIntExact(conf.getCodecBufferSize().toBytes()));
String prefix = conf.key(CACHE_KEY_PREFIX) + conf.getKeySeparator();
ResultSetCache cache = new RedisResultSetCache(RedisModulesUtils.connection(client, codec), prefix);
Expand Down Expand Up @@ -257,20 +258,9 @@ public static boolean isRegistered() {
return registeredDriver != null;
}

private static QueryRuleSession ruleSession(Config config, AbstractRedisClient redisClient) {
private QueryRuleSession ruleSession(Config config) {
QueryRuleSession ruleSession = QueryRuleSession.of(config.getRuleset());
config.getRuleset().addPropertyChangeListener(ruleSession);
if (configManagers.containsKey(config)) {
throw new IllegalStateException(
MessageFormat.format("Config manager already exists for config {0}", config));
}
StatefulRedisModulesConnection<String, String> connection = RedisModulesUtils.connection(redisClient);
try {
configManagers.put(config,
new ConfigManager<>(connection, config.key("config"), config.getRuleset(), config.getConfigStep()));
} catch (JsonProcessingException e) {
logger.log(Level.WARNING, "Could not initialize config manager", e);
}
return ruleSession;
}

Expand Down Expand Up @@ -314,7 +304,7 @@ public String keyspace() {

@Override
public Duration step() {
return config.getMetricsStep();
return Duration.ofMillis(config.getMetricsStep().toMillis());
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import io.airlift.units.DataSize;
import io.airlift.units.DataSize.Unit;
import io.airlift.units.Duration;
import io.lettuce.core.SslVerifyMode;

public class Config {

public static final String DEFAULT_KEYSPACE = "smartcache";
public static final String DEFAULT_KEY_SEPARATOR = ":";
public static final Duration DEFAULT_CONFIG_STEP = Duration.ofSeconds(10);
public static final Duration DEFAULT_METRICS_STEP = Duration.ofSeconds(60);
public static final Duration DEFAULT_CONFIG_STEP = new Duration(10, TimeUnit.SECONDS);
public static final Duration DEFAULT_METRICS_STEP = new Duration(60, TimeUnit.SECONDS);
public static final int DEFAULT_POOL_SIZE = 8;
public static final DataSize DEFAULT_BYTE_BUFFER_CAPACITY = DataSize.of(10, Unit.MEGABYTE);
private static final int DEFAULT_QUERY_CACHE_CAPACITY = 10000;
Expand Down Expand Up @@ -298,15 +299,15 @@ public static RulesetConfig of(RuleConfig... rules) {

public static class RuleConfig {

public static final long DEFAULT_TTL = 3600;
public static final Duration DEFAULT_TTL = new Duration(1, TimeUnit.HOURS);

private final PropertyChangeSupport support = new PropertyChangeSupport(this);

private String[] tables;
private String[] tablesAny;
private String[] tablesAll;
private String regex;
private long ttl = DEFAULT_TTL;
private Duration ttl = DEFAULT_TTL;

public RuleConfig() {
}
Expand Down Expand Up @@ -365,14 +366,13 @@ public void setTablesAll(String... tablesAll) {

/**
*
* @return Key expiration duration in seconds. Use 0 for no caching, -1 for no
* expiration
* @return Key expiration duration. Use a duration of zero for no caching
*/
public long getTtl() {
public Duration getTtl() {
return ttl;
}

public void setTtl(long ttl) {
public void setTtl(Duration ttl) {
support.firePropertyChange("ttl", this.ttl, ttl);
this.ttl = ttl;
}
Expand Down Expand Up @@ -417,12 +417,12 @@ public static final class Builder {
private String[] tablesAny;
private String[] tablesAll;
private String regex;
private long ttl = DEFAULT_TTL;
private Duration ttl = DEFAULT_TTL;

private Builder() {
}

public Builder ttl(long ttl) {
public Builder ttl(Duration ttl) {
this.ttl = ttl;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.redis.smartcache.core;

import java.time.Duration;
import java.util.Set;

public class Query {

public static final long TTL_NO_CACHING = 0;
public static final Duration TTL_NO_CACHING = Duration.ZERO;
public static final long TTL_NO_EXPIRATION = -1;

private final String id;
private final String sql;
private final Set<String> tables;
private long ttl = TTL_NO_CACHING;
private Duration ttl = TTL_NO_CACHING;

public Query(String id, String sql, Set<String> tables) {
this.id = id;
Expand All @@ -30,16 +31,19 @@ public Set<String> getTables() {
return tables;
}

public long getTtl() {
public Duration getTtl() {
return ttl;
}

public void setTtl(long ttl) {
public void setTtl(Duration ttl) {
if (ttl == null || ttl.isNegative()) {
throw new IllegalArgumentException("TTL duration must be greater than 0");
}
this.ttl = ttl;
}

public boolean isCaching() {
return ttl != TTL_NO_CACHING;
return !TTL_NO_CACHING.equals(ttl);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.time.Duration;
import java.util.List;
import java.util.function.Consumer;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -68,7 +69,8 @@ private static Rule<Query, Query> rule(RuleConfig rule) {
}

private static Consumer<Query> action(RuleConfig rule) {
return s -> s.setTtl(rule.getTtl());
Duration ttl = Duration.ofMillis(rule.getTtl().toMillis());
return s -> s.setTtl(ttl);
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.redis.smartcache.core;

import java.sql.ResultSet;
import java.time.Duration;

import com.redis.lettucemod.api.StatefulRedisModulesConnection;

import io.lettuce.core.SetArgs;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.internal.LettuceAssert;

Expand All @@ -28,8 +30,8 @@ public ResultSet get(String id) {
}

@Override
public void put(String id, long ttl, ResultSet resultSet) {
connection.sync().setex(key(id), ttl, resultSet);
public void put(String id, Duration ttl, ResultSet resultSet) {
connection.sync().set(key(id), resultSet, SetArgs.Builder.ex(ttl));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Duration;

public interface ResultSetCache {

Expand All @@ -15,11 +16,11 @@ public interface ResultSetCache {
/**
* Adds a ResultSet to the cache.
*
* @param key key to store the ResultSet under.
* @param ttl the key TTL in seconds.
* @param resultSet the ResultSet to store under the key.
* @param key key to store the ResultSet under
* @param ttl the key TTL
* @param resultSet the ResultSet to store under the key
* @throws SQLException if an error occurred while storing the ResultSet
*/
void put(String key, long ttl, ResultSet resultSet);
void put(String key, Duration ttl, ResultSet resultSet);

}
Loading

0 comments on commit 7b4c354

Please sign in to comment.