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 CLIENT TRACKINGINFO #2862

Merged
merged 10 commits into from
Aug 8, 2024
5 changes: 5 additions & 0 deletions src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ public RedisFuture<String> clientTracking(TrackingArgs args) {
return dispatch(commandBuilder.clientTracking(args));
}

@Override
public RedisFuture<TrackingInfo> clientTrackinginfo() {
return dispatch(commandBuilder.clientTrackinginfo());
}

@Override
public RedisFuture<Long> clientUnblock(long id, UnblockType type) {
return dispatch(commandBuilder.clientUnblock(id, type));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,11 @@ public Mono<String> clientTracking(TrackingArgs args) {
return createMono(() -> commandBuilder.clientTracking(args));
}

@Override
public Mono<TrackingInfo> clientTrackinginfo() {
return createMono(commandBuilder::clientTrackinginfo);
}

@Override
public Mono<Long> clientUnblock(long id, UnblockType type) {
return createMono(() -> commandBuilder.clientUnblock(id, type));
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/io/lettuce/core/RedisCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,12 @@ Command<K, V, String> clientTracking(TrackingArgs trackingArgs) {
return createCommand(CLIENT, new StatusOutput<>(codec), args);
}

Command<K, V, TrackingInfo> clientTrackinginfo() {
CommandArgs<K, V> args = new CommandArgs<>(codec).add(TRACKINGINFO);

return new Command<>(CLIENT, new ComplexOutput<>(codec, TrackingInfoParser.INSTANCE), args);
}

Command<K, V, Long> clientUnblock(long id, UnblockType type) {
LettuceAssert.notNull(type, "UnblockType " + MUST_NOT_BE_NULL);

Expand Down
165 changes: 165 additions & 0 deletions src/main/java/io/lettuce/core/TrackingInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* Copyright 2024, Redis Ltd. and Contributors
* All rights reserved.
*
* Licensed under the MIT License.
*/

package io.lettuce.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.List;

/**
* Contains the output of a <a href="https://redis.io/docs/latest/commands/client-trackinginfo/">CLIENT TRACKINGINFO</a>
* command.
*
* @author Tihomir Mateev
* @since 6.5
*/
public class TrackingInfo {

private final Set<TrackingFlag> flags = new HashSet<>();

private final long redirect;

private final List<String> prefixes = new ArrayList<>();

/**
* Constructor
*
* @param flags a {@link Set} of {@link TrackingFlag}s that the command returned
* @param redirect the client ID used for notification redirection, -1 when none
* @param prefixes a {@link List} of key prefixes for which notifications are sent to the client
*
* @see TrackingFlag
*/
public TrackingInfo(Set<TrackingFlag> flags, long redirect, List<String> prefixes) {
this.flags.addAll(flags);
this.redirect = redirect;
this.prefixes.addAll(prefixes);
}

/**
* @return set of all the {@link TrackingFlag}s currently enabled on the client connection
*/
public Set<TrackingFlag> getFlags() {
return Collections.unmodifiableSet(flags);
}

/**
* @return the client ID used for notification redirection, -1 when none
*/
public long getRedirect() {
return redirect;
}

/**
* @return a {@link List} of key prefixes for which notifications are sent to the client
*/
public List<String> getPrefixes() {
return Collections.unmodifiableList(prefixes);
}

@Override
public String toString() {
return "TrackingInfo{" + "flags=" + flags + ", redirect=" + redirect + ", prefixes=" + prefixes + '}';
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
TrackingInfo that = (TrackingInfo) o;
return redirect == that.redirect && Objects.equals(flags, that.flags) && Objects.equals(prefixes, that.prefixes);
}

@Override
public int hashCode() {
return Objects.hash(flags, redirect, prefixes);
}

/**
* CLIENT TRACKINGINFO flags
*
* @see <a href="https://redis.io/docs/latest/commands/client-trackinginfo/">CLIENT TRACKINGINFO</a>
*/
public enum TrackingFlag {

/**
* The connection isn't using server assisted client side caching.
*/
OFF,
/**
* Server assisted client side caching is enabled for the connection.
*/
ON,
/**
* The client uses broadcasting mode.
*/
BCAST,
/**
* The client does not cache keys by default.
*/
OPTIN,
/**
* The client caches keys by default.
*/
OPTOUT,
/**
* The next command will cache keys (exists only together with optin).
*/
CACHING_YES,
/**
* The next command won't cache keys (exists only together with optout).
*/
CACHING_NO,
/**
* The client isn't notified about keys modified by itself.
*/
NOLOOP,
/**
* The client ID used for redirection isn't valid anymore.
*/
BROKEN_REDIRECT;

/**
* Convert a given {@link String} flag to the corresponding {@link TrackingFlag}
*
* @param flag a {@link String} representation of the flag
* @return the resulting {@link TrackingFlag} or {@link IllegalArgumentException} if unrecognized
*/
public static TrackingFlag from(String flag) {
switch (flag.toLowerCase()) {
case "off":
return OFF;
case "on":
return ON;
case "bcast":
return BCAST;
case "optin":
return OPTIN;
case "optout":
return OPTOUT;
case "caching-yes":
return CACHING_YES;
case "caching-no":
return CACHING_NO;
case "noloop":
return NOLOOP;
case "broken_redirect":
return BROKEN_REDIRECT;
default:
throw new RuntimeException("Unsupported flag: " + flag);
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.lettuce.core.ShutdownArgs;
import io.lettuce.core.TrackingArgs;
import io.lettuce.core.UnblockType;
import io.lettuce.core.TrackingInfo;
import io.lettuce.core.protocol.CommandType;

/**
Expand Down Expand Up @@ -177,6 +178,14 @@ public interface RedisServerAsyncCommands<K, V> {
*/
RedisFuture<String> clientTracking(TrackingArgs args);

/**
* Returns information about the current client connection's use of the server assisted client side caching feature.
*
* @return {@link TrackingInfo}, for more information check the documentation
* @since 6.5
*/
RedisFuture<TrackingInfo> clientTrackinginfo();

/**
* Unblock the specified blocked client.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.lettuce.core.ShutdownArgs;
import io.lettuce.core.TrackingArgs;
import io.lettuce.core.UnblockType;
import io.lettuce.core.TrackingInfo;
import io.lettuce.core.protocol.CommandType;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
Expand Down Expand Up @@ -177,6 +178,14 @@ public interface RedisServerReactiveCommands<K, V> {
*/
Mono<String> clientTracking(TrackingArgs args);

/**
* Returns information about the current client connection's use of the server assisted client side caching feature.
*
* @return {@link TrackingInfo}, for more information check the documentation
* @since 6.5
*/
Mono<TrackingInfo> clientTrackinginfo();

/**
* Unblock the specified blocked client.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.lettuce.core.KillArgs;
import io.lettuce.core.ShutdownArgs;
import io.lettuce.core.TrackingArgs;
import io.lettuce.core.TrackingInfo;
import io.lettuce.core.UnblockType;
import io.lettuce.core.protocol.CommandType;

Expand Down Expand Up @@ -176,6 +177,14 @@ public interface RedisServerCommands<K, V> {
*/
String clientTracking(TrackingArgs args);

/**
* Returns information about the current client connection's use of the server assisted client side caching feature.
*
* @return {@link TrackingInfo}, for more information check the documentation
* @since 6.5
*/
TrackingInfo clientTrackinginfo();

/**
* Unblock the specified blocked client.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
*/
package io.lettuce.core.cluster.api.async;

import java.util.Date;
import java.util.List;
import java.util.Map;

import java.util.List;
import java.util.Date;
import io.lettuce.core.ClientListArgs;
import io.lettuce.core.FlushMode;
import io.lettuce.core.KillArgs;
import io.lettuce.core.TrackingArgs;
import io.lettuce.core.UnblockType;
import io.lettuce.core.TrackingInfo;
import io.lettuce.core.protocol.CommandType;

/**
Expand Down Expand Up @@ -175,6 +175,14 @@ public interface NodeSelectionServerAsyncCommands<K, V> {
*/
AsyncExecutions<String> clientTracking(TrackingArgs args);

/**
* Returns information about the current client connection's use of the server assisted client side caching feature.
*
* @return {@link TrackingInfo}, for more information check the documentation
* @since 6.5
*/
AsyncExecutions<TrackingInfo> clientTrackinginfo();

/**
* Unblock the specified blocked client.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.lettuce.core.KillArgs;
import io.lettuce.core.TrackingArgs;
import io.lettuce.core.UnblockType;
import io.lettuce.core.TrackingInfo;
import io.lettuce.core.protocol.CommandType;

/**
Expand Down Expand Up @@ -163,7 +164,7 @@ public interface NodeSelectionServerCommands<K, V> {
* @return simple-string-reply {@code OK} if the connection name was successfully set.
* @since 6.3
*/
Executions<String> clientSetinfo(String key, V value);
Executions<String> clientSetinfo(String key, String value);

/**
* Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages
Expand All @@ -175,6 +176,14 @@ public interface NodeSelectionServerCommands<K, V> {
*/
Executions<String> clientTracking(TrackingArgs args);

/**
* Returns information about the current client connection's use of the server assisted client side caching feature.
*
* @return {@link TrackingInfo}, for more information check the documentation
* @since 6.5
*/
Executions<TrackingInfo> clientTrackinginfo();

/**
* Unblock the specified blocked client.
*
Expand Down
Loading
Loading