@Override protected <T> CompletionStage<T> performRequest(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, Function<ResponseCollector<T>, CompletionStage<T>> invoker, RpcOptions rpcOptions) { if (command instanceof LockControlCommand) { lockCount++; } else if (command instanceof ClusteredGetCommand) { clusterGet++; } else { otherCount++; } return super.performRequest(targets, command, collector, invoker, rpcOptions); } }
@Override public final void sendToAll(ReplicableCommand command, DeliverOrder deliverOrder) { setTopologyId(command); performSend(getTransport().getMembers(), command, c -> { realOne.sendToAll(command, deliverOrder); return null; }); }
@Deprecated @Override public final Map<Address, Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand command, RpcOptions rpcOptions) { return realOne.blocking(invokeRemotelyAsync(recipients, command, rpcOptions)); }
@Override public final void sendToMany(Collection<Address> destinations, ReplicableCommand command, DeliverOrder deliverOrder) { setTopologyId(command); performSend(destinations, command, c -> { realOne.sendToMany(destinations, command, deliverOrder); return null; }); }
@Override public final <T> CompletionStage<T> invokeCommandOnAll(ReplicableCommand command, ResponseCollector<T> collector, RpcOptions rpcOptions) { return performRequest(getTransport().getMembers(), command, collector, c -> realOne.invokeCommandOnAll(command, c, rpcOptions), rpcOptions); }
@Deprecated @Override public final CompletableFuture<Map<Address, Response>> invokeRemotelyAsync(Collection<Address> recipients, ReplicableCommand command, RpcOptions rpcOptions) { Collection<Address> targets = recipients != null ? recipients : getTransport().getMembers(); setTopologyId(command); MapResponseCollector collector = MapResponseCollector.ignoreLeavers(shouldIgnoreLeavers(rpcOptions), targets.size()); if (rpcOptions.responseMode().isSynchronous()) { return invokeCommand(targets, command, collector, rpcOptions).toCompletableFuture(); } else { sendToMany(recipients, command, rpcOptions.deliverOrder()); return CompletableFutures.completedEmptyMap(); } }
@Override public final Map<Address, Response> invokeRemotely(Map<Address, ReplicableCommand> rpcs, RpcOptions options) { try { rpcs.forEach((address, command) -> setTopologyId(command)); return CompletableFutures.await( invokeCommands(rpcs.keySet(), rpcs::get, MapResponseCollector.validOnly(rpcs.size()), options) .toCompletableFuture()); } catch (ExecutionException | InterruptedException e) { throw Util.rewrapAsCacheException(e); } }
@Override protected <T> void performSend(Collection<Address> targets, ReplicableCommand command, Function<ResponseCollector<T>, CompletionStage<T>> invoker) { if (command instanceof TxCompletionNotificationCommand) { releaseLocksLatch.countDown(); log.tracef("Skipping TxCompletionNotificationCommand"); } else { super.performSend(targets, command, invoker); } } };
private void setTopologyId(ReplicableCommand command) { if (command instanceof TopologyAffectedCommand && ((TopologyAffectedCommand) command).getTopologyId() < 0) { ((TopologyAffectedCommand) command).setTopologyId(getTopologyId()); } }
@Override public final <T> CompletionStage<T> invokeCommands(Collection<Address> targets, Function<Address, ReplicableCommand> commandGenerator, ResponseCollector<T> collector, RpcOptions rpcOptions) { // Split the invocation into multiple unicast requests CommandsRequest<T> action = new CommandsRequest<>(targets, collector); for (Address target : targets) { if (rpcOptions.deliverOrder() != DeliverOrder.TOTAL && target.equals(realOne.getAddress())) continue; invokeCommand(target, commandGenerator.apply(target), SingletonMapResponseCollector.ignoreLeavers(), rpcOptions) .whenComplete(action); } return action.resultFuture; }
@Override public final void sendTo(Address destination, ReplicableCommand command, DeliverOrder deliverOrder) { setTopologyId(command); performSend(Collections.singleton(destination), command, c -> { realOne.sendTo(destination, command, deliverOrder); return null; }); }
@Override protected <T> CompletionStage<T> performRequest(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, Function<ResponseCollector<T>, CompletionStage<T>> invoker, RpcOptions rpcOptions) { if (command instanceof RollbackCommand) { queue.add("rollback"); } else if (command instanceof PrepareCommand) { queue.add("prepare"); } return super.performRequest(targets, command, collector, invoker, rpcOptions); } }
@Override protected <T> CompletionStage<T> performRequest(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, Function<ResponseCollector<T>, CompletionStage<T>> invoker, RpcOptions rpcOptions) { if (command instanceof LockControlCommand) { throw new TimeoutException("Exception expected!"); } return super.performRequest(targets, command, collector, invoker, rpcOptions); } }
@Override public final <T> CompletionStage<T> invokeCommand(Address target, ReplicableCommand command, ResponseCollector<T> collector, RpcOptions rpcOptions) { return performRequest(Collections.singleton(target), command, collector, c -> realOne.invokeCommand(target, command, c, rpcOptions), rpcOptions); }
@Override public final <T> CompletionStage<T> invokeCommand(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, RpcOptions rpcOptions) { return performRequest(targets, command, collector, c -> realOne.invokeCommand(targets, command, c, rpcOptions), rpcOptions); }
@Override public final <T> CompletionStage<T> invokeCommandStaggered(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, RpcOptions rpcOptions) { return performRequest(targets, command, collector, c -> realOne.invokeCommand(targets, command, c, rpcOptions), rpcOptions); }
@Override protected <T> CompletionStage<T> performRequest(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, Function<ResponseCollector<T>, CompletionStage<T>> invoker, RpcOptions rpcOptions) { return super.performRequest(targets, command, collector, invoker, rpcOptions) .thenApply(responseObject -> { if (!(responseObject instanceof Map)) { log.debugf("Single response for command %s: %s", command, responseObject); return responseObject; } Map<Address, Response> newResponseMap = new LinkedHashMap<>(); boolean containsLastResponseAddress = false; for (Map.Entry<Address, Response> entry : ((Map<Address, Response>) responseObject) .entrySet()) { if (lastResponse.equals(entry.getKey())) { containsLastResponseAddress = true; continue; } newResponseMap.put(entry.getKey(), entry.getValue()); } if (containsLastResponseAddress) { newResponseMap.put(lastResponse, ((Map<Address, Response>) responseObject).get(lastResponse)); } log.debugf("Responses for command %s are %s", command, newResponseMap.values()); return (T) newResponseMap; }); } }
@Override protected <T> CompletionStage<T> performRequest(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, Function<ResponseCollector<T>, CompletionStage<T>> invoker, RpcOptions rpcOptions) { if (command instanceof RevokeBiasCommand) { if (throwBefore) throw new RemoteException("Induced", null); if (throwInFuture) { return CompletableFutures.completedExceptionFuture(new RemoteException("Induced", null)); } } return super.performRequest(targets, command, collector, invoker, rpcOptions); } }
@Override protected <T> CompletionStage<T> performRequest(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, Function<ResponseCollector<T>, CompletionStage<T>> invoker, RpcOptions rpcOptions) { return super.performRequest(targets, command, collector, invoker, rpcOptions) .thenApply(result -> { log.debugf("After invoke remotely %s. Responses=%s", command, result); if (triggered || !(command instanceof PrepareCommand)) return result; log.debugf("Triggering %s and %s", TX1_LOCKED, TX1_UNSURE); triggered = true; try { sequencer.advance(TX1_LOCKED); sequencer.advance(TX1_UNSURE); } catch (TimeoutException | InterruptedException e) { throw new CacheException(e); } Map<Address, Response> newResult = new HashMap<>(); ((Map<Address, Response>) result).forEach((address, response) -> newResult.put(address, UnsureResponse.INSTANCE)); log.debugf("After invoke remotely %s. New Responses=%s", command, newResult); return (T) newResult; }); } }
@Override protected <T> CompletionStage<T> performRequest(Collection<Address> targets, ReplicableCommand command, ResponseCollector<T> collector, Function<ResponseCollector<T>, CompletionStage<T>> invoker, RpcOptions rpcOptions) { boolean accept; try { accept = matcher.accept(command); StateSequencerUtil.advanceMultiple(stateSequencer, accept, statesBefore); } catch (Exception e) { throw new RuntimeException(e); } CompletionStage<T> stage = super.performRequest(targets, command, collector, invoker, rpcOptions); if (stage != null) { return stage.whenComplete((result, throwable) -> advanceNoThrow(accept)); } else { advanceNoThrow(accept); return null; } }