final Address target = entry.getKey();
Map<Object, InternalCacheValue> state = entry.getValue();
if (trace)
log.tracef("pushing %d keys to %s", state.size(), target);
final RehashControlCommand cmd = cf.buildRehashControlCommand(RehashControlCommand.Type.APPLY_STATE, self,
state, chOld, chNew);
rpcManager.invokeRemotelyInFuture(Collections.singleton(target), cmd,
false, stateTransferFuture, configuration.getRehashRpcTimeout());
}
// TODO Allow APPLY_STATE RehashControlCommand to skip transaction blocking, so we can unblock new transactions
// only after we have invalidated the keys removed from this cache
// For transactions TransactionTable should have already rolled back the transactions touching those keys,
// but it still might be a problem for non-transactional writes.
needToUnblockTransactions = false;
distributionManager.getTransactionLogger().unblockNewTransactions();
// wait to see if all servers received the new state
// TODO should we retry the state transfer operation if it failed on some of the nodes?
try {
stateTransferFuture.get();
} catch (ExecutionException e) {
log.errorTransferringState(e);
}
// Notify listeners of completion of rehashing
notifier.notifyDataRehashed(oldCacheSet, newCacheSet, newViewId, false);
// now we can invalidate the keys
try {
InvalidateCommand invalidateCmd = cf.buildInvalidateFromL1Command(true, removedKeys);
InvocationContext ctx = icc.createNonTxInvocationContext();
invalidateCmd.perform(ctx);
} catch (Throwable t) {
log.failedToInvalidateKeys(t);
}
if (trace) {
if (removedKeys.size() > 0)
log.tracef("removed %d keys", removedKeys.size());
log.tracef("data container has now %d keys", dataContainer.size());
}
} else {
if (trace) log.trace("Rehash not enabled, so not pushing state");
}
} finally {
if (needToUnblockTransactions) {
distributionManager.getTransactionLogger().unblockNewTransactions();
}
}
// now we can inform the coordinator that we have finished our push
Transport t = rpcManager.getTransport();
if (t.isCoordinator()) {
distributionManager.markNodePushCompleted(newViewId, t.getAddress());
} else {
final RehashControlCommand cmd = cf.buildRehashControlCommand(RehashControlCommand.Type.NODE_PUSH_COMPLETED, self, newViewId);
// doesn't matter when the coordinator receives the command, the transport will ensure that it eventually gets there
rpcManager.invokeRemotely(Collections.singleton(t.getCoordinator()), cmd, false);
}
} finally {