I am using redis with java using Jedis as redis-client. I have a class
public class RedisDBManager
which has methods which call Jedis to execute the commands on redis.
Sample method inside RedisDBManager
public Set<NTuple> zrangeWithScores(String key, int min, int max)
{
JedisSentinelPool localPool = redisSentinelPool;
Jedis redis = null;
try
{
redis = getResource();
Set<Tuple> tupleSet = redis.zrangeWithScores(key, min, max);
Set<NTuple> tuples = new LinkedHashSet<>();
for (Tuple tuple : tupleSet) {
tuples.add(new NTuple(tuple.getElement(), tuple.getScore()));
}
return tuples;
}
catch (JedisConnectionException jex) {
logger.error("Creating new connection since it encountered Jedis Connection Exception: ",jex);
createNewConnectionPool(localPool);
try {
redis = getResource();
Set<Tuple> tupleSet = redis.zrangeWithScores(key, min, max);
Set<NTuple> tuples = new LinkedHashSet<>();
for (Tuple tuple : tupleSet) {
tuples.add(new NTuple(tuple.getElement(), tuple.getScore()));
}
return tuples;
}
catch (Exception e){
logger.error("Exception: ", e);
return null;
}
}
catch (Exception ex) {
logger.error("Exception: ", ex);
return null;
}
finally
{
if (redis != null)
{
returnResource(redis);
}
}
}
Here the method getResource returns a resource from JedisSentinelPool.
I want a pipelining method inside this class so that it takes a list of commands to execute and returns the responses as a list. I want that any construct of Jedis should not be used outside of RedisDBManager as in outside methods should call pipelining method which takes care of all responsibilities.
This question is similar to this question. It differs in a way that i want to use different redis commands as well and get their responses.
My current incomplete approach is modifying all methods in RedisDBManager to accept whether to pipeline it or not to a thread local Pipeline object and then have a pipelining method which syncs this pipeline object and returns the responses.
Something like :
public Set<NTuple> zrangeWithScores(String key, int min, int max, boolean pipelined) {
...
try
{
if (pipelined) {
pipeline = getExistingThreadLocalPipelineObject();
pipeline.zrangeWithScores(key, min, max);
} else {
redis = getResource();
...
return tuples;
}
catch (JedisConnectionException jex) {
...
if (pipelined) {
pipeline = getExistingThreadLocalPipelineObject();
pipeline.zrangeWithScores(key, min, max);
} else {
redis = getResource();
...
return tuples;
...
}
public List<MyResponse> syncPipeline() {
pipeline = getExistingThreadLocalPipelineObject();
pipeline.sync();
//process all responses and send
}
Is there any better or simpler approach? Thanks.