Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for cache namespace #8

Closed
wants to merge 1 commit into from
Closed
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: 7 additions & 0 deletions build/context/admin/cdriver/Redis.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ component extends="Cache" {
description = "Port Redis is listening on.",
type = "text"
)
,field(
displayName = "Namespace",
name = "namespace",
defaultValue = "lucee:cache",
required = false,
description = "Keys namespace. If using the same Redis instance for more than one cache use a unique namespace to avoid keys names clashing."
)

,group("Authentication","Authentication Credentials if necessary.")
,field(displayName = "Password",
Expand Down
4 changes: 2 additions & 2 deletions build/context/admin/cdriver/RedisSentinel.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ component extends="Cache" {
displayName = "Namespace",
name = "namespace",
defaultValue = "lucee:cache",
required = true,
description = "Keys namespace. Be sure that any cache use a unique namespace to avoid keys names clashing."
required = false,
description = "Keys namespace. If using the same Redis instance for more than one cache use a unique namespace to avoid keys names clashing."
)

,group("Authentication","Authentication Credentials if necessary.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public abstract class AbstractRedisCache extends CacheSupport {
private int maxIdle;
private int minIdle;
private int defaultExpire;
private String namespace;

public void init(Config config, String[] cacheName, Struct[] arguments) {
// Not used at the moment
Expand All @@ -49,6 +50,9 @@ public void init(Struct arguments) throws IOException {

defaultExpire = caster.toIntValue(arguments.get("timeToLiveSeconds", null), 0);

namespace = caster.toString(arguments.get("namespace", null), null);
if (Util.isEmpty(namespace)) namespace = null;

// for config
maxTotal = caster.toIntValue(arguments.get("maxTotal", null), 0);
maxIdle = caster.toIntValue(arguments.get("maxIdle", null), 0);
Expand Down Expand Up @@ -76,11 +80,11 @@ public CacheEntry getCacheEntry(String key) throws IOException {
key = validateKey(key);
String val = null;
try {
val = conn.get(key);
val = conn.get(RedisCacheUtils.addNamespace(namespace, key));
}
catch (JedisDataException jde) {
String msg = jde.getMessage() + "";
if (msg.startsWith("WRONGTYPE")) val = conn.lpop(key);
if (msg.startsWith("WRONGTYPE")) val = conn.lpop(RedisCacheUtils.addNamespace(namespace, key));
}
if (val == null) throw new IOException("Cache key [" + key + "] does not exists");
return new RedisCacheEntry(this, key, evaluate(val), val.length());
Expand Down Expand Up @@ -112,23 +116,31 @@ public void put(String key, Object val, Long idle, Long expire) {
// fields.put("value", value);
// fields.put("hitCount", "0");
// conn.hmset(key, fields);
conn.set(validateKey(key), serialize(val));

// TODO different to default?
// System.err.println("idle:" + idle);
// System.err.println("expire:" + expire);
// System.err.println("defaultExpire:" + defaultExpire);

int ex = 0;
int ex = defaultExpire;

if (expire != null) {
ex = (int) (expire / 1000);
ex = (int) (expire / 1000);
}
else {
ex = defaultExpire;
else if (idle != null) {
// note: if this cache is being used as a session store
// then idle will be passed in as -1 when a new session
// is created and first stored. Avoid setting `ex` in
// this case so we don't get a cache item without a TTL
// when the cache has a default TTL
if (idle >= 0) {
ex = (int) (idle / 1000);
}
}

if (ex > 0) {
// System.err.println(key + ":" + ex);
conn.expire(validateKey(key), ex);
conn.setex(RedisCacheUtils.addNamespace(namespace, validateKey(key)), ex, serialize(val));
} else {
conn.set(RedisCacheUtils.addNamespace(namespace, validateKey(key)), serialize(val));
}
}
catch (PageException e) {
Expand All @@ -143,7 +155,7 @@ public void put(String key, Object val, Long idle, Long expire) {
public boolean contains(String key) {
Jedis conn = jedisSilent();
try {
return conn.exists(validateKey(key));
return conn.exists(RedisCacheUtils.addNamespace(namespace, validateKey(key)));
}
finally {
RedisCacheUtils.close(conn);
Expand All @@ -154,7 +166,7 @@ public boolean contains(String key) {
public boolean remove(String key) throws IOException {
Jedis conn = jedis();
try {
return conn.del(validateKey(key)) > 0;
return conn.del(RedisCacheUtils.addNamespace(namespace, validateKey(key))) > 0;
}
finally {
RedisCacheUtils.close(conn);
Expand All @@ -165,7 +177,7 @@ public boolean remove(String key) throws IOException {
public List<String> keys() throws IOException {
Jedis conn = jedis();
try {
return toList(conn.keys("*"));
return toList(conn.keys(RedisCacheUtils.addNamespace(namespace, "*")));
}
finally {
RedisCacheUtils.close(conn);
Expand Down Expand Up @@ -208,7 +220,7 @@ private List<String> toList(Set<String> keys) throws IOException {
List<String> list = new ArrayList<String>();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
list.add(it.next());
list.add(RedisCacheUtils.removeNamespace(namespace, it.next()));
}
return list;
}
Expand All @@ -227,7 +239,7 @@ public CacheEntry getQuiet(String key, CacheEntry defaultValue) {
@Override
public int clear() throws IOException {
Jedis conn = jedis();
Set<String> set = conn.keys("*");
Set<String> set = conn.keys(RedisCacheUtils.addNamespace(namespace, "*"));
String[] keys = engine.getListUtil().toStringArray(set);
if (keys.length == 0) return 0;
return engine.getCastUtil().toIntValue(conn.del(keys), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ public class RedisCacheUtils {
private RedisCacheUtils() {}

public static String removeNamespace(String nameSpace, String key) {
if (nameSpace != null && key.startsWith(nameSpace)) return key.replace(nameSpace + ":", "");
if (nameSpace != null && key.startsWith(nameSpace.toLowerCase())) return key.replace(nameSpace.toLowerCase() + ":", "");
return key;

}

public static String addNamespace(String nameSpace, String key) throws IOException { // TODO rethink this
if (nameSpace == null) return key.toLowerCase();
public static String addNamespace(String nameSpace, String key) {
if (nameSpace == null) return key; // key is already lowercased due to validateKey call

if (key.startsWith(nameSpace + ":")) {
if (key.startsWith(nameSpace.toLowerCase() + ":")) {
return key;
}
String res = nameSpace + ':' + key;
return res.toLowerCase();// setting case sensitive
String res = nameSpace.toLowerCase() + ':' + key; // setting case sensitive
return res;
}

public static void close(Jedis jedis) {
Expand Down