redis.clients.jedis.MultiNodePipelineBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jedis Show documentation
Show all versions of jedis Show documentation
Jedis is a blazingly small and sane Redis java client.
package redis.clients.jedis;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.graph.GraphCommandObjects;
import redis.clients.jedis.providers.ConnectionProvider;
import redis.clients.jedis.util.IOUtils;
public abstract class MultiNodePipelineBase extends PipelineBase {
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* The number of processes for {@code sync()}. If you have enough cores for client (and you have
* more than 3 cluster nodes), you may increase this number of workers.
* Suggestion: ≤ cluster nodes.
*/
public static volatile int MULTI_NODE_PIPELINE_SYNC_WORKERS = 3;
private final Map>> pipelinedResponses;
private final Map connections;
private volatile boolean syncing = false;
public MultiNodePipelineBase(CommandObjects commandObjects) {
super(commandObjects);
pipelinedResponses = new LinkedHashMap<>();
connections = new LinkedHashMap<>();
}
/**
* Sub-classes must call this method, if graph commands are going to be used.
* @param connectionProvider connection provider
*/
protected final void prepareGraphCommands(ConnectionProvider connectionProvider) {
GraphCommandObjects graphCommandObjects = new GraphCommandObjects(connectionProvider);
graphCommandObjects.setBaseCommandArgumentsCreator((comm) -> this.commandObjects.commandArguments(comm));
super.setGraphCommands(graphCommandObjects);
}
protected abstract HostAndPort getNodeKey(CommandArguments args);
protected abstract Connection getConnection(HostAndPort nodeKey);
@Override
protected final Response appendCommand(CommandObject commandObject) {
HostAndPort nodeKey = getNodeKey(commandObject.getArguments());
Queue> queue;
Connection connection;
if (pipelinedResponses.containsKey(nodeKey)) {
queue = pipelinedResponses.get(nodeKey);
connection = connections.get(nodeKey);
} else {
Connection newOne = getConnection(nodeKey);
connections.putIfAbsent(nodeKey, newOne);
connection = connections.get(nodeKey);
if (connection != newOne) {
log.debug("Duplicate connection to {}, closing it.", nodeKey);
IOUtils.closeQuietly(newOne);
}
pipelinedResponses.putIfAbsent(nodeKey, new LinkedList<>());
queue = pipelinedResponses.get(nodeKey);
}
connection.sendCommand(commandObject.getArguments());
Response response = new Response<>(commandObject.getBuilder());
queue.add(response);
return response;
}
@Override
public void close() {
try {
sync();
} finally {
connections.values().forEach(IOUtils::closeQuietly);
}
}
@Override
public final void sync() {
if (syncing) {
return;
}
syncing = true;
ExecutorService executorService = Executors.newFixedThreadPool(MULTI_NODE_PIPELINE_SYNC_WORKERS);
CountDownLatch countDownLatch = new CountDownLatch(pipelinedResponses.size());
Iterator>>> pipelinedResponsesIterator
= pipelinedResponses.entrySet().iterator();
while (pipelinedResponsesIterator.hasNext()) {
Map.Entry>> entry = pipelinedResponsesIterator.next();
HostAndPort nodeKey = entry.getKey();
Queue> queue = entry.getValue();
Connection connection = connections.get(nodeKey);
executorService.submit(() -> {
try {
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy