package redis.clients.jedis; import java.io.Closeable; import java.util.ArrayList; import java.util.List; import redis.clients.jedis.exceptions.JedisDataException; public class Pipeline extends MultiKeyPipelineBase implements Closeable { private MultiResponseBuilder currentMulti; private class MultiResponseBuilder extends Builder<List<Object>> { private List<Response<?>> responses = new ArrayList<Response<?>>(); @Override public List<Object> build(Object data) { @SuppressWarnings("unchecked") List<Object> list = (List<Object>) data; List<Object> values = new ArrayList<Object>(); if (list.size() != responses.size()) { throw new JedisDataException("Expected data size " + responses.size() + " but was " + list.size()); } for (int i = 0; i < list.size(); i++) { Response<?> response = responses.get(i); response.set(list.get(i)); Object builtResponse; try { builtResponse = response.get(); } catch (JedisDataException e) { builtResponse = e; } values.add(builtResponse); } return values; } public void setResponseDependency(Response<?> dependency) { for (Response<?> response : responses) { response.setDependency(dependency); } } public void addResponse(Response<?> response) { responses.add(response); } } @Override protected <T> Response<T> getResponse(Builder<T> builder) { if (currentMulti != null) { super.getResponse(BuilderFactory.STRING); // Expected QUEUED Response<T> lr = new Response<T>(builder); currentMulti.addResponse(lr); return lr; } else { return super.getResponse(builder); } } public void setClient(Client client) { this.client = client; } @Override protected Client getClient(byte[] key) { return client; } @Override protected Client getClient(String key) { return client; } public void clear() { if (isInMulti()) { discard(); } sync(); } public boolean isInMulti() { return currentMulti != null; } /** * Synchronize pipeline by reading all responses. This operation close the pipeline. In order to * get return values from pipelined commands, capture the different Response<?> of the * commands you execute. */ public void sync() { if (getPipelinedResponseLength() > 0) { List<Object> unformatted = client.getMany(getPipelinedResponseLength()); for (Object o : unformatted) { generateResponse(o); } } } /** * Synchronize pipeline by reading all responses. This operation close the pipeline. Whenever * possible try to avoid using this version and use Pipeline.sync() as it won't go through all the * responses and generate the right response type (usually it is a waste of time). * @return A list of all the responses in the order you executed them. */ public List<Object> syncAndReturnAll() { if (getPipelinedResponseLength() > 0) { List<Object> unformatted = client.getMany(getPipelinedResponseLength()); List<Object> formatted = new ArrayList<Object>(); for (Object o : unformatted) { try { formatted.add(generateResponse(o).get()); } catch (JedisDataException e) { formatted.add(e); } } return formatted; } else { return java.util.Collections.<Object> emptyList(); } } public Response<String> discard() { if (currentMulti == null) throw new JedisDataException("DISCARD without MULTI"); client.discard(); currentMulti = null; return getResponse(BuilderFactory.STRING); } public Response<List<Object>> exec() { if (currentMulti == null) throw new JedisDataException("EXEC without MULTI"); client.exec(); Response<List<Object>> response = super.getResponse(currentMulti); currentMulti.setResponseDependency(response); currentMulti = null; return response; } public Response<String> multi() { if (currentMulti != null) throw new JedisDataException("MULTI calls can not be nested"); client.multi(); Response<String> response = getResponse(BuilderFactory.STRING); // Expecting // OK currentMulti = new MultiResponseBuilder(); return response; } @Override public void close() { clear(); } }