|
|
@@ -21,6 +21,7 @@ import org.elasticsearch.cluster.IncompatibleClusterStateVersionException;
|
|
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
|
|
import org.elasticsearch.cluster.node.DiscoveryNodeRole;
|
|
|
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
|
|
+import org.elasticsearch.common.CheckedSupplier;
|
|
|
import org.elasticsearch.common.bytes.ReleasableBytesReference;
|
|
|
import org.elasticsearch.common.compress.Compressor;
|
|
|
import org.elasticsearch.common.compress.CompressorFactory;
|
|
|
@@ -329,6 +330,7 @@ public class PublicationTransportHandler {
|
|
|
assert refCount() > 0;
|
|
|
assert publishRequest.getAcceptedState() == newState : "state got switched on us";
|
|
|
assert transportService.getThreadPool().getThreadContext().isSystemContext();
|
|
|
+ final var newStateVersion = newState.version();
|
|
|
if (destination.equals(discoveryNodes.getLocalNode())) {
|
|
|
|
|
|
// The transport service normally avoids serializing/deserializing requests to the local node but here we have special
|
|
|
@@ -339,26 +341,38 @@ public class PublicationTransportHandler {
|
|
|
// because it only makes sense on the local node (e.g. UnassignedInfo#unassignedTimeNanos).
|
|
|
|
|
|
final boolean isVotingOnlyNode = discoveryNodes.getLocalNode().getRoles().contains(DiscoveryNodeRole.VOTING_ONLY_NODE_ROLE);
|
|
|
- logger.trace("handling cluster state version [{}] locally on [{}]", newState.version(), destination);
|
|
|
+ logger.trace("handling cluster state version [{}] locally on [{}]", newStateVersion, destination);
|
|
|
transportService.getThreadPool()
|
|
|
.executor(ThreadPool.Names.CLUSTER_COORDINATION)
|
|
|
- .execute(transportService.getThreadPool().getThreadContext().preserveContext(ActionRunnable.supply(listener, () -> {
|
|
|
- if (isVotingOnlyNode) {
|
|
|
- // Voting-only nodes publish their cluster state to other nodes in order to freshen the state held on other full
|
|
|
- // master nodes, but then fail the publication before committing. However there's no need to freshen our local
|
|
|
- // state so we can fail right away.
|
|
|
- throw new TransportException(
|
|
|
- new ElasticsearchException("voting-only node skipping local publication to " + destination)
|
|
|
- );
|
|
|
- } else {
|
|
|
- return handlePublishRequest.apply(publishRequest);
|
|
|
- }
|
|
|
- })));
|
|
|
+ .execute(
|
|
|
+ transportService.getThreadPool()
|
|
|
+ .getThreadContext()
|
|
|
+ .preserveContext(ActionRunnable.supply(listener, new CheckedSupplier<>() {
|
|
|
+ @Override
|
|
|
+ public PublishWithJoinResponse get() {
|
|
|
+ if (isVotingOnlyNode) {
|
|
|
+ // Voting-only nodes publish their cluster state to other nodes in order to freshen the state held
|
|
|
+ // on other full master nodes, but then fail the publication before committing. However there's no
|
|
|
+ // need to freshen our local state so we can fail right away.
|
|
|
+ throw new TransportException(
|
|
|
+ new ElasticsearchException("voting-only node skipping local publication to " + destination)
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ return handlePublishRequest.apply(publishRequest);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String toString() {
|
|
|
+ return "handling cluster state version [" + newStateVersion + "] locally on [" + destination + "]";
|
|
|
+ }
|
|
|
+ }))
|
|
|
+ );
|
|
|
} else if (sendFullVersion || previousState.nodes().nodeExists(destination) == false) {
|
|
|
- logger.trace("sending full cluster state version [{}] to [{}]", newState.version(), destination);
|
|
|
+ logger.trace("sending full cluster state version [{}] to [{}]", newStateVersion, destination);
|
|
|
sendFullClusterState(destination, listener);
|
|
|
} else {
|
|
|
- logger.trace("sending cluster state diff for version [{}] to [{}]", newState.version(), destination);
|
|
|
+ logger.trace("sending cluster state diff for version [{}] to [{}]", newStateVersion, destination);
|
|
|
sendClusterStateDiff(destination, listener);
|
|
|
}
|
|
|
}
|