![JAR search and dependency download from the Maven repository](/logo.png)
org.infinispan.server.resp.commands.cluster.SLOTS Maven / Gradle / Ivy
Show all versions of infinispan-server-resp Show documentation
package org.infinispan.server.resp.commands.cluster;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.util.concurrent.CompletableFutures;
import org.infinispan.distribution.DistributionManager;
import org.infinispan.distribution.ch.ConsistentHash;
import org.infinispan.factories.impl.BasicComponentRegistry;
import org.infinispan.factories.impl.ComponentRef;
import org.infinispan.manager.CacheManagerInfo;
import org.infinispan.manager.ClusterExecutor;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.remoting.transport.Address;
import org.infinispan.security.actions.SecurityActions;
import org.infinispan.server.core.transport.NettyTransport;
import org.infinispan.server.resp.ByteBufPool;
import org.infinispan.server.resp.Resp3Handler;
import org.infinispan.server.resp.RespCommand;
import org.infinispan.server.resp.RespErrorUtil;
import org.infinispan.server.resp.RespRequestHandler;
import org.infinispan.server.resp.RespServer;
import org.infinispan.server.resp.commands.Resp3Command;
import org.infinispan.server.resp.serialization.ByteBufferUtils;
import org.infinispan.server.resp.serialization.JavaObjectSerializer;
import org.infinispan.server.resp.serialization.Resp3Response;
import org.infinispan.server.resp.serialization.Resp3Type;
import org.infinispan.server.resp.serialization.RespConstants;
import org.infinispan.topology.CacheTopology;
import io.netty.channel.ChannelHandlerContext;
import net.jcip.annotations.GuardedBy;
/**
* `CLUSTER SLOTS
` command.
*
* As of Redis version 7.0.0, this command is regarded as deprecated, and {@link SHARDS} is the recommended alternative.
* This command retrieves information about the slot distribution in the cluster. Also including connection information
* of all members.
*
* @since 15.0
* @see SHARDS
* @see Redis Documentation
* @author José Bolina
*/
public class SLOTS extends RespCommand implements Resp3Command {
private static final BiConsumer, ByteBufPool> SERIALIZER = (res, alloc) -> {
ByteBufferUtils.writeNumericPrefix(RespConstants.ARRAY, res.size(), alloc);
for (SlotInformation si : res) {
Resp3Response.write(si, alloc, si);
}
};
@GuardedBy("this")
private CompletionStage> lastExecution = null;
@GuardedBy("this")
private ConsistentHash lastAcceptedHash = null;
public SLOTS() {
super(2, 0, 0, 0);
}
@Override
public CompletionStage perform(Resp3Handler handler, ChannelHandlerContext ctx, List arguments) {
AdvancedCache, ?> respCache = handler.cache();
DistributionManager dm = respCache.getDistributionManager();
if (dm == null) {
RespErrorUtil.customError("This instance has cluster support disabled", handler.allocator());
return handler.myStage();
}
CacheTopology topology = dm.getCacheTopology();
ConsistentHash hash = topology.getCurrentCH();
if (hash == null) {
RespErrorUtil.customError("No consistent hash available", handler.allocator());
return handler.myStage();
}
synchronized (this) {
if (!hash.equals(lastAcceptedHash)) {
lastExecution = getSlotsInformation(handler, hash);
lastAcceptedHash = hash;
}
}
return handler.stageToReturn(lastExecution, ctx, SERIALIZER);
}
private static CompletionStage> getSlotsInformation(Resp3Handler handler, ConsistentHash hash) {
return requestNodesNetworkInformation(hash.getMembers(), handler)
.thenApply(information -> {
List response = new ArrayList<>();
SegmentSlotRelation ssr = handler.respServer().segmentSlotRelation();
// These two will always be initialized in first loop below
int previousOwnedSegment = -1;
List ownersForSegment = null;
int slotWidth = ssr.slotWidth();
int totalSegmentCount = hash.getNumSegments();
for (int i = 0; i < totalSegmentCount; ++i) {
List currentOwners = hash.locateOwnersForSegment(i);
if (!currentOwners.equals(ownersForSegment) || i == (totalSegmentCount - 1)) {
if (ownersForSegment != null) {
int start = previousOwnedSegment * slotWidth;
int end = (i * slotWidth) - 1;
List nodes = new ArrayList<>();
for (Address owner: ownersForSegment) {
nodes.add(NodeInformation.create(information.get(owner)));
}
response.add(new SlotInformation(start, end, nodes));
}
ownersForSegment = currentOwners;
previousOwnedSegment = i;
}
}
return response;
});
}
private static CompletionStage