DATAREDIS-267 - Add support for 'CLIENT KILL'.
Killing a client connection can be done via 'RedisConnection' and 'RedisOperations' using 'jedis', 'lettuce' and 'srp'. We use dedicated parameters for host and port building up the redis format (host:port) for connection identification. Original Pull Request: #56
This commit is contained in:
committed by
Thomas Darimont
parent
1c47330ec9
commit
6a6d03eb4c
@@ -2191,6 +2191,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
|
||||
return this.delegate.time();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#killClient(byte[])
|
||||
*/
|
||||
@Override
|
||||
public void killClient(String host, int port) {
|
||||
this.delegate.killClient(host, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if pipelined and tx results should be deserialized to Strings. If false, results of
|
||||
* {@link #closePipeline()} and {@link #exec()} will be of the type returned by the underlying connection
|
||||
|
||||
@@ -161,4 +161,14 @@ public interface RedisServerCommands {
|
||||
* @since 1.1
|
||||
*/
|
||||
Long time();
|
||||
|
||||
/**
|
||||
* Closes a given client connection identified by {@literal ip:port}.
|
||||
*
|
||||
* @param host of connection to close.
|
||||
* @param port of connection to close
|
||||
* @since 1.3
|
||||
*/
|
||||
void killClient(String host, int port);
|
||||
|
||||
}
|
||||
|
||||
@@ -2808,6 +2808,26 @@ public class JedisConnection implements RedisConnection {
|
||||
return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#killClient(byte[])
|
||||
*/
|
||||
@Override
|
||||
public void killClient(String host, int port) {
|
||||
|
||||
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
|
||||
|
||||
if (isQueueing() || isPipelined()) {
|
||||
throw new UnsupportedOperationException("'CLIENT KILL' is not supported in transaction / pipline mode.");
|
||||
}
|
||||
|
||||
try {
|
||||
this.jedis.clientKill(String.format("%s:%s", host, port));
|
||||
} catch (Exception e) {
|
||||
throw convertJedisAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if pipelined results should be converted to the expected data type. If false, results of
|
||||
* {@link #closePipeline()} and {@link #exec()} will be of the type returned by the Jedis driver
|
||||
|
||||
@@ -1185,4 +1185,9 @@ public class JredisConnection implements RedisConnection {
|
||||
public Long time() {
|
||||
throw new UnsupportedOperationException("The 'TIME' command is not supported by the JRedis driver.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killClient(String host, int port) {
|
||||
throw new UnsupportedOperationException("The 'CLIENT KILL' command is not supported by the JRedis driver.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2903,6 +2903,23 @@ public class LettuceConnection implements RedisConnection {
|
||||
return Converters.toTimeMillis(new String(result.get(0)), new String(result.get(1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killClient(String host, int port) {
|
||||
|
||||
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
|
||||
|
||||
String client = String.format("%s:%s", host, port);
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new LettuceStatusResult(getAsyncConnection().clientKill(client)));
|
||||
return;
|
||||
}
|
||||
getConnection().clientKill(client);
|
||||
} catch (Exception e) {
|
||||
convertLettuceAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if pipelined and transaction results should be converted to the expected data type. If false, results of
|
||||
* {@link #closePipeline()} and {@link #exec()} will be of the type returned by the Lettuce driver
|
||||
|
||||
@@ -2222,6 +2222,24 @@ public class SrpConnection implements RedisConnection {
|
||||
return SrpConverters.toTimeAsLong(reply.data());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killClient(String host, int port) {
|
||||
|
||||
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
|
||||
|
||||
String client = String.format("%s:%s", host, port);
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new SrpStatusResult(pipeline.client_kill(client)));
|
||||
return;
|
||||
}
|
||||
|
||||
this.client.client_kill(client);
|
||||
} catch (Exception e) {
|
||||
throw convertSrpAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> closeTransaction() {
|
||||
List<Object> results = Collections.emptyList();
|
||||
if (txTracker != null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
* useful option for extensibility and testability (as it can be easily mocked or stubbed).
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public interface RedisOperations<K, V> {
|
||||
|
||||
@@ -284,4 +285,13 @@ public interface RedisOperations<K, V> {
|
||||
RedisSerializer<?> getHashKeySerializer();
|
||||
|
||||
RedisSerializer<?> getHashValueSerializer();
|
||||
|
||||
/**
|
||||
* Closes a given client connection identified by {@literal ip:port} given in {@code client}.
|
||||
*
|
||||
* @param host of connection to close.
|
||||
* @param port of connection to close
|
||||
* @since 1.3
|
||||
*/
|
||||
void killClient(String host, int port);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -69,6 +69,7 @@ import org.springframework.util.CollectionUtils;
|
||||
* <b>This is the central class in Redis support</b>.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
* @param <K> the Redis key type against which the template works (usually a String)
|
||||
* @param <V> the Redis value type against which the template works
|
||||
* @see StringRedisTemplate
|
||||
@@ -989,4 +990,21 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
public <HK, HV> HashOperations<K, HK, HV> opsForHash() {
|
||||
return new DefaultHashOperations<K, HK, HV>(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.RedisOperations#killClient(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void killClient(final String host, final int port) {
|
||||
|
||||
execute(new RedisCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
connection.killClient(host, port);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user