DATAREDIS-462 - Support lettuce ClientResources.

Add ClientResources to LettuceConnectionFactory. Add TestClientResources for managed resources during tests and reuse ClientResources as much as possible in tests.

Original Pull Request: #169
This commit is contained in:
Mark Paluch
2016-02-15 15:46:43 +01:00
committed by Christoph Strobl
parent 0fa1319b8f
commit b58c18f85b
26 changed files with 391 additions and 40 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2016 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.
@@ -17,6 +17,7 @@ package org.springframework.data.redis.connection.lettuce;
import java.util.concurrent.TimeUnit;
import com.lambdaworks.redis.resource.ClientResources;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
@@ -50,6 +51,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
private String password;
private long timeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS);
private RedisSentinelConfiguration sentinelConfiguration;
private ClientResources clientResources;
/**
* Constructs a new <code>DefaultLettucePool</code> instance with default settings.
@@ -101,7 +103,14 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
@SuppressWarnings({ "rawtypes" })
public void afterPropertiesSet() {
this.client = new RedisClient(getRedisURI());
if(clientResources != null) {
this.client = RedisClient.create(clientResources, getRedisURI());
}
else {
this.client = RedisClient.create(getRedisURI());
}
client.setDefaultTimeout(timeout, TimeUnit.MILLISECONDS);
this.internalPool = new GenericObjectPool<RedisAsyncConnection>(new LettuceFactory(client, dbIndex), poolConfig);
}
@@ -273,6 +282,24 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
this.timeout = timeout;
}
/**
* Returns the client resources to reuse the client infrastructure.
* @return client resources
* @since 1.7
*/
public ClientResources getClientResources() {
return clientResources;
}
/**
* Sets the client resources to reuse the client infrastructure.
* @param clientResources
* @since 1.7
*/
public void setClientResources(ClientResources clientResources) {
this.clientResources = clientResources;
}
@SuppressWarnings("rawtypes")
private static class LettuceFactory extends BasePooledObjectFactory<RedisAsyncConnection> {

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.lambdaworks.redis.resource.ClientResources;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
@@ -95,6 +96,7 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
private RedisSentinelConfiguration sentinelConfiguration;
private RedisClusterConfiguration clusterConfiguration;
private ClusterCommandExecutor clusterCommandExecutor;
private ClientResources clientResources;
/**
* Constructs a new <code>LettuceConnectionFactory</code> instance with default settings.
@@ -388,6 +390,24 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
this.password = password;
}
/**
* Returns the client resources to reuse the client infrastructure.
* @return client resources
* @since 1.7
*/
public ClientResources getClientResources() {
return clientResources;
}
/**
* Sets the client resources to reuse the client infrastructure.
* @param clientResources
* @since 1.7
*/
public void setClientResources(ClientResources clientResources) {
this.clientResources = clientResources;
}
/**
* Returns the shutdown timeout for shutting down the RedisClient (in milliseconds).
*
@@ -469,7 +489,11 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
if (isRedisSentinelAware()) {
RedisURI redisURI = getSentinelRedisURI();
return new RedisClient(redisURI);
if(clientResources == null) {
return RedisClient.create(redisURI);
}
return RedisClient.create(clientResources, redisURI);
}
if (isClusterAware()) {
@@ -486,7 +510,13 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
initialUris.add(redisURI);
}
RedisClusterClient clusterClient = new RedisClusterClient(initialUris);
RedisClusterClient clusterClient;
if(clientResources == null) {
clusterClient = RedisClusterClient.create(initialUris);
}
else {
clusterClient = RedisClusterClient.create(clientResources, initialUris);
}
this.clusterCommandExecutor = new ClusterCommandExecutor(
new LettuceClusterConnection.LettuceClusterTopologyProvider(clusterClient),
@@ -504,8 +534,11 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
builder.withPassword(password);
}
builder.withTimeout(timeout, TimeUnit.MILLISECONDS);
RedisClient client = new RedisClient(builder.build());
return client;
if(clientResources != null) {
return RedisClient.create(clientResources, builder.build());
}
return RedisClient.create(builder.build());
}
private RedisURI getSentinelRedisURI() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2016 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.
@@ -20,6 +20,8 @@ import java.util.List;
import com.lambdaworks.redis.RedisClient;
import com.lambdaworks.redis.RedisSentinelAsyncConnection;
import com.lambdaworks.redis.RedisURI;
import com.lambdaworks.redis.resource.ClientResources;
import org.springframework.data.redis.ExceptionTranslationStrategy;
import org.springframework.data.redis.FallbackExceptionTranslationStrategy;
import org.springframework.data.redis.connection.NamedNode;
@@ -51,12 +53,26 @@ public class LettuceSentinelConnection implements RedisSentinelConnection {
/**
* Creates a {@link LettuceSentinelConnection} with a client for the supplied {@code host} and {@code port}.
* @param host hostname
* @param host hostname must not be {@literal null}
* @param port sentinel port
*/
public LettuceSentinelConnection(String host, int port) {
Assert.notNull(host, "Cannot created LettuceSentinelConnection using 'null' as host.");
redisClient = new RedisClient(host, port);
Assert.notNull(host, "Cannot create LettuceSentinelConnection using 'null' as host.");
redisClient = RedisClient.create(new RedisURI.Builder().redis(host, port).build());
init();
}
/**
* Creates a {@link LettuceSentinelConnection} with a client for the supplied {@code host} and {@code port} and reuse
* existing {@code clientResources}.
* @param clientResources must not be {@literal null}
* @param host hostname must not be {@literal null}
* @param port sentinel port
*/
public LettuceSentinelConnection(ClientResources clientResources, String host, int port) {
Assert.notNull(clientResources, "Cannot create LettuceSentinelConnection using 'null' as ClientResources.");
Assert.notNull(host, "Cannot create LettuceSentinelConnection using 'null' as host.");
redisClient = RedisClient.create(clientResources, new RedisURI.Builder().redis(host, port).build());
init();
}