use of org.infinispan.remoting.transport.impl.SingletonMapResponseCollector in project infinispan by infinispan.
the class ScatteredDistributionInterceptor method visitGetAllCommand.
@Override
public Object visitGetAllCommand(InvocationContext ctx, GetAllCommand command) throws Throwable {
LocalizedCacheTopology cacheTopology = checkTopology(command);
if (command.hasAnyFlag(FlagBitSets.CACHE_MODE_LOCAL | FlagBitSets.SKIP_REMOTE_LOOKUP | FlagBitSets.SKIP_OWNERSHIP_CHECK)) {
return invokeNext(ctx, command);
}
if (ctx.isOriginLocal()) {
Map<Address, List<Object>> remoteKeys = new HashMap<>();
for (Object key : command.getKeys()) {
if (ctx.lookupEntry(key) != null) {
continue;
}
DistributionInfo info = cacheTopology.getDistribution(key);
if (info.primary() == null) {
throw OutdatedTopologyException.RETRY_NEXT_TOPOLOGY;
} else if (!info.isPrimary()) {
remoteKeys.computeIfAbsent(info.primary(), k -> new ArrayList<>()).add(key);
}
}
if (remoteKeys.isEmpty()) {
return invokeNext(ctx, command);
}
ClusteredGetAllFuture sync = new ClusteredGetAllFuture(remoteKeys.size());
for (Map.Entry<Address, List<Object>> remote : remoteKeys.entrySet()) {
List<Object> keys = remote.getValue();
ClusteredGetAllCommand clusteredGetAllCommand = cf.buildClusteredGetAllCommand(keys, command.getFlagsBitSet(), null);
clusteredGetAllCommand.setTopologyId(command.getTopologyId());
SingletonMapResponseCollector collector = SingletonMapResponseCollector.ignoreLeavers();
CompletionStage<Map<Address, Response>> rpcFuture = rpcManager.invokeCommand(remote.getKey(), clusteredGetAllCommand, collector, rpcManager.getSyncRpcOptions());
rpcFuture.whenComplete(((responseMap, throwable) -> handleGetAllResponse(responseMap, throwable, ctx, keys, sync)));
}
return asyncInvokeNext(ctx, command, sync);
} else {
// remote
for (Object key : command.getKeys()) {
if (ctx.lookupEntry(key) == null) {
return UnsureResponse.INSTANCE;
}
}
return invokeNext(ctx, command);
}
}
use of org.infinispan.remoting.transport.impl.SingletonMapResponseCollector in project infinispan by infinispan.
the class NonTxDistributionInterceptor method handleRemoteSegmentsForReadWriteManyCommand.
private <C extends WriteCommand, Item> void handleRemoteSegmentsForReadWriteManyCommand(C command, WriteManyCommandHelper<C, ?, Item> helper, MergingCompletableFuture<Object> allFuture, MutableInt offset, Address member, IntSet segments, LocalizedCacheTopology topology) {
final int myOffset = offset.value;
// TODO: here we iterate through all entries - is the ReadOnlySegmentAwareMap really worth it?
C copy = helper.copyForPrimary(command, topology, segments);
copy.setTopologyId(command.getTopologyId());
int size = helper.getItems(copy).size();
offset.value += size;
if (size <= 0) {
allFuture.countDown();
return;
}
// Send the command to primary owner
SingletonMapResponseCollector collector = SingletonMapResponseCollector.validOnly();
rpcManager.invokeCommand(member, copy, collector, rpcManager.getSyncRpcOptions()).whenComplete((responses, throwable) -> {
if (throwable != null) {
allFuture.completeExceptionally(throwable);
} else {
// FIXME Dan: The response cannot be a CacheNotFoundResponse at this point
SuccessfulResponse response = getSuccessfulResponseOrFail(responses, allFuture, rsp -> allFuture.completeExceptionally(OutdatedTopologyException.RETRY_NEXT_TOPOLOGY));
if (response == null) {
return;
}
Object responseValue = response.getResponseValue();
MergingCompletableFuture.moveListItemsToFuture(responseValue, allFuture, myOffset);
allFuture.countDown();
}
});
}
use of org.infinispan.remoting.transport.impl.SingletonMapResponseCollector in project infinispan by infinispan.
the class NonTxDistributionInterceptor method handleSegmentsForWriteOnlyManyCommand.
private <C extends WriteCommand, Container, Item> void handleSegmentsForWriteOnlyManyCommand(InvocationContext ctx, C command, WriteManyCommandHelper<C, Container, Item> helper, CountDownCompletableFuture allFuture, Address member, IntSet segments, LocalizedCacheTopology topology) {
if (member.equals(rpcManager.getAddress())) {
Container myItems = filterAndWrap(ctx, command, segments, helper);
C localCommand = helper.copyForLocal(command, myItems);
localCommand.setTopologyId(command.getTopologyId());
// Local keys are backed up in the handler, and counters on allFuture are decremented when the backup
// calls complete.
invokeNextAndFinally(ctx, localCommand, createLocalInvocationHandler(allFuture, segments, helper, (f, rv) -> {
}, topology));
return;
}
C copy = helper.copyForPrimary(command, topology, segments);
copy.setTopologyId(command.getTopologyId());
int size = helper.getItems(copy).size();
if (size <= 0) {
allFuture.countDown();
return;
}
SingletonMapResponseCollector collector = SingletonMapResponseCollector.validOnly();
rpcManager.invokeCommand(member, copy, collector, rpcManager.getSyncRpcOptions()).whenComplete((responseMap, throwable) -> {
if (throwable != null) {
allFuture.completeExceptionally(throwable);
} else {
// FIXME Dan: The response cannot be a CacheNotFoundResponse at this point
if (getSuccessfulResponseOrFail(responseMap, allFuture, rsp -> allFuture.completeExceptionally(OutdatedTopologyException.RETRY_NEXT_TOPOLOGY)) == null) {
return;
}
allFuture.countDown();
}
});
}
use of org.infinispan.remoting.transport.impl.SingletonMapResponseCollector in project infinispan by infinispan.
the class ScatteredDistributionInterceptor method visitReadOnlyManyCommand.
@Override
public Object visitReadOnlyManyCommand(InvocationContext ctx, ReadOnlyManyCommand command) throws Throwable {
if (command.hasAnyFlag(FlagBitSets.CACHE_MODE_LOCAL | FlagBitSets.SKIP_REMOTE_LOOKUP)) {
return handleLocalOnlyReadManyCommand(ctx, command, command.getKeys());
}
LocalizedCacheTopology cacheTopology = checkTopology(command);
if (!ctx.isOriginLocal()) {
return handleRemoteReadManyCommand(ctx, command, command.getKeys());
}
if (command.getKeys().isEmpty()) {
return Stream.empty();
}
ConsistentHash ch = cacheTopology.getReadConsistentHash();
int estimateForOneNode = 2 * command.getKeys().size() / ch.getMembers().size();
Function<Address, List<Object>> createList = k -> new ArrayList<>(estimateForOneNode);
Map<Address, List<Object>> requestedKeys = new HashMap<>();
List<Object> localKeys = null;
for (Object key : command.getKeys()) {
if (ctx.lookupEntry(key) != null) {
if (localKeys == null) {
localKeys = new ArrayList<>();
}
localKeys.add(key);
continue;
}
DistributionInfo info = cacheTopology.getDistribution(key);
assert !info.isPrimary();
if (info.primary() == null) {
throw AllOwnersLostException.INSTANCE;
}
requestedKeys.computeIfAbsent(info.primary(), createList).add(key);
}
MergingCompletableFuture<Object> allFuture = new MergingCompletableFuture<>(requestedKeys.size() + (localKeys == null ? 0 : 1), new Object[command.getKeys().size()], Arrays::stream);
int offset = 0;
if (localKeys != null) {
offset += localKeys.size();
ReadOnlyManyCommand localCommand = new ReadOnlyManyCommand(command).withKeys(localKeys);
invokeNextAndFinally(ctx, localCommand, (rCtx, rCommand, rv, throwable) -> {
if (throwable != null) {
allFuture.completeExceptionally(throwable);
} else {
try {
((Stream) rv).collect(new ArrayCollector(allFuture.results));
allFuture.countDown();
} catch (Throwable t) {
allFuture.completeExceptionally(t);
}
}
});
}
for (Map.Entry<Address, List<Object>> addressKeys : requestedKeys.entrySet()) {
List<Object> keysForAddress = addressKeys.getValue();
ReadOnlyManyCommand remoteCommand = new ReadOnlyManyCommand(command).withKeys(keysForAddress);
remoteCommand.setTopologyId(command.getTopologyId());
Set<Address> target = Collections.singleton(addressKeys.getKey());
int myOffset = offset;
SingletonMapResponseCollector collector = SingletonMapResponseCollector.ignoreLeavers();
CompletionStage<Map<Address, Response>> rpc = rpcManager.invokeCommand(target, remoteCommand, collector, rpcManager.getSyncRpcOptions());
rpc.whenComplete((responseMap, throwable) -> {
if (throwable != null) {
allFuture.completeExceptionally(throwable);
return;
}
SuccessfulResponse response = getSuccessfulResponseOrFail(responseMap, allFuture, rsp -> allFuture.completeExceptionally(rsp instanceof UnsureResponse ? OutdatedTopologyException.RETRY_NEXT_TOPOLOGY : AllOwnersLostException.INSTANCE));
if (response == null) {
return;
}
try {
Object[] values = (Object[]) response.getResponseValue();
if (values != null) {
System.arraycopy(values, 0, allFuture.results, myOffset, values.length);
allFuture.countDown();
} else {
allFuture.completeExceptionally(new IllegalStateException("Unexpected response value " + response.getResponseValue()));
}
} catch (Throwable t) {
allFuture.completeExceptionally(t);
}
});
offset += keysForAddress.size();
}
return asyncValue(allFuture);
}
Aggregations