-1

I have written a class where I have connection pool and pipelined and the way to use this class would be something like (i removed a loop, but setKey would be happening in the loop):

private Redis redis = new Redis();
redis.setKey(path, keyValueOutput, 3000);
redis.setKey(path, keyValueOutput, 3000);
redis.setKey(path, keyValueOutput, 3000);
if (redis.getPipelineCount() > 200) {
   redis.syncKeys();
   System.out.println("200 items added");
}

So as soon as the number of items on pipeline is more than 200 i sync items and clear pipeline and start again. The question is how with this setup correcly return connections back to the pool.

public class Redis {
    private JedisPoolConfig poolConfig = new JedisPoolConfig();
    private JedisPool jedisPool = new JedisPool(poolConfig,"localhost", 6379);
    private Jedis jedis = jedisPool.getResource();
    
    private Pipeline pipeline = jedis.pipelined();
    private int pipelineCount = 0;

    public void setKey(String path, Map<String, String> keyValueOutput, int expireTime) {
        this.pipeline.hset(path, keyValueOutput);
        this.pipeline.expire(path, expireTime);
        this.pipelineCount = this.pipelineCount + 1;
    }

    public void syncKeys() {
        this.pipeline.sync();
        this.pipelineCount = 0;
    }

    public int getPipelineCount() {
        return this.pipelineCount;
    }

    public void close() {
        this.jedis.close();
    }

}

As far as I understand I have to wrap jedisPool.getResource() into try block, but I can't put my head around how to combine it with my pipeline and counter together.

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            Pipeline p = jedis.pipelined();
            p.sync()
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
Arthur Zangiev
  • 1,438
  • 3
  • 14
  • 21

1 Answers1

2

syncKeys() method would be right place to do this. You may need some sort of locking for safety. I've used synchronized as an example.

    public synchronized void syncKeys() {
        this.pipeline.sync();
        this.jedis.close();
        this.jedis = null;
        this.pipelineCount = 0;
    }

Beyond the question, is your application multi-threaded? If not, then you're using JedisPool unncessarily. Simple Jedis should be enough. Otherwise, you're using Pool wrong. For example, your Redis object is limited use at most one Jedis object at a certain time. This will be a bottleneck in a multi-threaded scenario.

sazzad
  • 5,740
  • 6
  • 25
  • 42
  • The appication is not multithreaded at the moment, but i would like to use this class in multithreaded scenario in future. That's why I would like to structure it the right way at first place and use Pool instead of Redis. – Arthur Zangiev Mar 21 '21 at 14:39
  • In terms of workflow, can i create connection ```jedisPool.getResource()``` create pipeline and set 200 items, sync, set more 200, sync and at the end do ```jedis.close()``` ? – Arthur Zangiev Mar 21 '21 at 23:53
  • You _CAN_. But the flow you're describing means you won't need more than one connection at a time. Which means `new Jedis(...)` is better suited than `jedisPool.getResource()`. – sazzad Mar 22 '21 at 09:53