Skip to content

Commit

Permalink
Merge pull request quarkusio#44856 from thibaultmeyer/feature/44693-c…
Browse files Browse the repository at this point in the history
…ache_redis_allow_usage_cachename
  • Loading branch information
cescoffier authored Dec 2, 2024
2 parents 2d19846 + 4147c6d commit 2c31260
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 14 deletions.
19 changes: 15 additions & 4 deletions docs/src/main/asciidoc/cache-redis-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ include::{includes}/extension-status.adoc[]
When using Redis as the backend for Quarkus cache, each cached item will be stored in Redis:

- The backend uses the _<default>_ Redis client (if not configured otherwise), so make sure it's configured (or use the xref:redis-dev-services.adoc[Redis Dev Service])
- the Redis key is built as follows: `cache:$cache-name:$cache-key`, where `cache-key` is the key the application uses.
- the Redis key is built as follows: `cache:{cache-name}:{cache-key}`, where `cache-key` is the key the application uses and `cache:{cache-name}` the prefix.
- the value is encoded to JSON if needed


Expand Down Expand Up @@ -118,10 +118,11 @@ include::{generated-dir}/config/quarkus-redis-cache.adoc[opts=optional, leveloff

== Configure the Redis key

By default, the Redis backend stores the entry using the following keys: `cache:$cache-name:$cache-key`, where `cache-key` is the key the application uses.
So, you can find all the entries for a single cache using the Redis `KEYS` command: `KEYS cache:$cache-name:*`
By default, the Redis backend stores the entry using the following keys pattern: `cache:{cache-name}:{cache-key}`, where `cache-key` is the key the application uses and `cache:{cache-name}` the prefix. The variable `{cache-name}` is resolved from the value set in the cache annotations.
So, you can find all the entries for a single cache using the Redis `KEYS` command: `KEYS cache:{cache-name}:*`

The prefix can be configured by using the `prefix` property:

The `cache:$cache-name:` segment can be configured using the `prefix` property:


[source, properties]
Expand All @@ -135,6 +136,16 @@ quarkus.cache.redis.expensiveResourceCache.prefix=my-expensive-cache

In these cases, you can find all the keys managed by the default cache using `KEYS my-cache:*`, and all the keys managed by the `expensiveResourceCache` cache using: `KEYS my-expensive-cache:*`.


----
# Default configuration
# The variable "{cache-name}" is resolved from the value set in the cache annotations.
quarkus.cache.redis.prefix=my-cache-{cache-name}
----

In this latest example, you can find all the keys managed by the default cache using `KEYS my-cache-{cache-name}:*`.


== Enable optimistic locking

The access to the cache can be _direct_ or use https://redis.io/docs/manual/transactions/#optimistic-locking-using-check-and-set[optimistic locking].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,15 +397,11 @@ public Uni<?> apply(List<String> listOfKeys) {
}

String computeActualKey(String key) {
if (cacheInfo.prefix != null) {
return cacheInfo.prefix + ":" + key;
} else {
return "cache:" + getName() + ":" + key;
}
return getKeyPrefix() + ":" + key;
}

Object computeUserKey(String key) {
String prefix = cacheInfo.prefix != null ? cacheInfo.prefix : "cache:" + getName();
String prefix = getKeyPrefix();
if (!key.startsWith(prefix + ":")) {
return null; // Not a key handle by the cache.
}
Expand All @@ -414,10 +410,14 @@ Object computeUserKey(String key) {
}

private String getKeyPattern() {
return getKeyPrefix() + ":*";
}

private String getKeyPrefix() {
if (cacheInfo.prefix != null) {
return cacheInfo.prefix + ":" + "*";
return cacheInfo.prefix.replace("{cache-name}", getName());
} else {
return "cache:" + getName() + ":" + "*";
return "cache:" + getName();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ public class RedisCacheRuntimeConfig {
Optional<Duration> expireAfterAccess;

/**
* the key prefix allowing to identify the keys belonging to the cache.
* If not set, use "cache:$cache-name"
* The key prefix allowing to identify the keys belonging to the cache.
* If not set, the value "{@code cache:{cache-name}}" will be used. The variable
* "{@code {cache-name}}" is resolved from the value set in the cache annotations.
*/
@ConfigItem
public Optional<String> prefix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,39 @@ void clear() {
}
}

@Test
public void testComputeActualKey() {
RedisCacheInfo info = new RedisCacheInfo();
info.name = "foo";
info.prefix = null;
info.expireAfterWrite = Optional.of(Duration.ofSeconds(2));

RedisCacheImpl cache = new RedisCacheImpl(info, vertx, redis, BLOCKING_ALLOWED);
assertThat(cache.computeActualKey("keyname")).isEqualTo("cache:foo:keyname");
}

@Test
public void testComputeActualKeyWithCustomPrefix() {
RedisCacheInfo info = new RedisCacheInfo();
info.name = "foo";
info.prefix = "my-prefix";
info.expireAfterWrite = Optional.of(Duration.ofSeconds(2));

RedisCacheImpl cache = new RedisCacheImpl(info, vertx, redis, BLOCKING_ALLOWED);
assertThat(cache.computeActualKey("keyname")).isEqualTo("my-prefix:keyname");
}

@Test
public void testComputeActualKeyWithCustomPrefixUsingCacheNameVariable() {
RedisCacheInfo info = new RedisCacheInfo();
info.name = "foo";
info.prefix = "my-prefix:{cache-name}";
info.expireAfterWrite = Optional.of(Duration.ofSeconds(2));

RedisCacheImpl cache = new RedisCacheImpl(info, vertx, redis, BLOCKING_ALLOWED);
assertThat(cache.computeActualKey("keyname")).isEqualTo("my-prefix:foo:keyname");
}

@Test
public void testPutInTheCache() {
String k = UUID.randomUUID().toString();
Expand Down

0 comments on commit 2c31260

Please sign in to comment.