InvocationContextContainer icc = cache.getAdvancedCache().getInvocationContextContainer();
DistributionManager dm = cache.getAdvancedCache().getDistributionManager();
InterceptorChain invoker = registry.getComponent(InterceptorChain.class);
CommandsFactory factory = registry.getComponent(CommandsFactory.class);
MapReduceCommand cmd = null;
MapReduceCommand selfCmd = null;
Map<Address, Response> results = new HashMap<Address, Response>();
if (inputTaskKeysEmpty()) {
cmd = factory.buildMapReduceCommand(mapper, reducer, rpc.getAddress(), keys);
selfCmd = cmd;
try {
log.debug("Invoking %s across entire cluster ", cmd);
Map<Address, Response> map = rpc.invokeRemotely(null, cmd, true, false);
log.debug("Invoked %s across entire cluster, results are %s", cmd, map);
results.putAll(map);
} catch (Throwable e) {
throw new CacheException("Could not invoke MapReduce task on remote nodes ", e);
}
} else {
Map<Address, List<KIn>> keysToNodes = mapKeysToNodes();
log.debug("Keys to nodes mapping is " + keysToNodes);
List<MapReduceFuture> futures = new ArrayList<MapReduceFuture>();
for (Entry<Address, List<KIn>> e : keysToNodes.entrySet()) {
Address address = e.getKey();
List<KIn> keys = e.getValue();
if (address.equals(rpc.getAddress())) {
selfCmd = factory.buildMapReduceCommand(mapper, reducer, rpc.getAddress(), keys);
} else {
cmd = factory.buildMapReduceCommand(mapper, reducer, rpc.getAddress(), keys);
try {
log.debug("Invoking %s on %s", cmd, address);
MapReduceFuture future = new MapReduceFuture();
futures.add(future);
rpc.invokeRemotelyInFuture(Collections.singleton(address), cmd, future);
log.debug("Invoked %s on %s ", cmd, address);
} catch (Exception ex) {
throw new CacheException("Could not invoke MapReduceTask on remote node " + address, ex);
}
}
}
for (MapReduceFuture future : futures) {
Map<Address, Response> result;
try {
result = (Map<Address, Response>) future.get();
results.putAll(result);
log.debug("Received result from future %s", result);
} catch (Exception e1) {
throw new CacheException("Could not retrieve MapReduceTask result from remote node", e1);
}
}
}
boolean selfInvoke = selfCmd != null;
Object localCommandResult = null;
if (selfInvoke) {
log.debug("Invoking %s locally", cmd);
selfCmd.init(factory, invoker, icc, dm, rpc.getAddress());
try {
localCommandResult = selfCmd.perform(null);
log.debug("Invoked %s locally", cmd);
} catch (Throwable e1) {
throw new CacheException("Could not invoke MapReduce task locally ", e1);
}
}