Search in sources :

Example 1 with BlockingClusterStatePublishResponseHandler

use of org.elasticsearch.discovery.BlockingClusterStatePublishResponseHandler in project elasticsearch by elastic.

the class PublishClusterStateAction method innerPublish.

private void innerPublish(final ClusterChangedEvent clusterChangedEvent, final Set<DiscoveryNode> nodesToPublishTo, final SendingController sendingController, final boolean sendFullVersion, final Map<Version, BytesReference> serializedStates, final Map<Version, BytesReference> serializedDiffs) {
    final ClusterState clusterState = clusterChangedEvent.state();
    final ClusterState previousState = clusterChangedEvent.previousState();
    final TimeValue publishTimeout = discoverySettings.getPublishTimeout();
    final long publishingStartInNanos = System.nanoTime();
    for (final DiscoveryNode node : nodesToPublishTo) {
        // we don't send full version if node didn't exist in the previous version of cluster state
        if (sendFullVersion || !previousState.nodes().nodeExists(node)) {
            sendFullClusterState(clusterState, serializedStates, node, publishTimeout, sendingController);
        } else {
            sendClusterStateDiff(clusterState, serializedDiffs, serializedStates, node, publishTimeout, sendingController);
        }
    }
    sendingController.waitForCommit(discoverySettings.getCommitTimeout());
    try {
        long timeLeftInNanos = Math.max(0, publishTimeout.nanos() - (System.nanoTime() - publishingStartInNanos));
        final BlockingClusterStatePublishResponseHandler publishResponseHandler = sendingController.getPublishResponseHandler();
        sendingController.setPublishingTimedOut(!publishResponseHandler.awaitAllNodes(TimeValue.timeValueNanos(timeLeftInNanos)));
        if (sendingController.getPublishingTimedOut()) {
            DiscoveryNode[] pendingNodes = publishResponseHandler.pendingNodes();
            // everyone may have just responded
            if (pendingNodes.length > 0) {
                logger.warn("timed out waiting for all nodes to process published state [{}] (timeout [{}], pending nodes: {})", clusterState.version(), publishTimeout, pendingNodes);
            }
        }
    } catch (InterruptedException e) {
        // ignore & restore interrupt
        Thread.currentThread().interrupt();
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) BlockingClusterStatePublishResponseHandler(org.elasticsearch.discovery.BlockingClusterStatePublishResponseHandler) TimeValue(org.elasticsearch.common.unit.TimeValue)

Example 2 with BlockingClusterStatePublishResponseHandler

use of org.elasticsearch.discovery.BlockingClusterStatePublishResponseHandler in project elasticsearch by elastic.

the class PublishClusterStateAction method publish.

/**
     * publishes a cluster change event to other nodes. if at least minMasterNodes acknowledge the change it is committed and will
     * be processed by the master and the other nodes.
     * <p>
     * The method is guaranteed to throw a {@link org.elasticsearch.discovery.Discovery.FailedToCommitClusterStateException}
     * if the change is not committed and should be rejected.
     * Any other exception signals the something wrong happened but the change is committed.
     */
public void publish(final ClusterChangedEvent clusterChangedEvent, final int minMasterNodes, final Discovery.AckListener ackListener) throws Discovery.FailedToCommitClusterStateException {
    final DiscoveryNodes nodes;
    final SendingController sendingController;
    final Set<DiscoveryNode> nodesToPublishTo;
    final Map<Version, BytesReference> serializedStates;
    final Map<Version, BytesReference> serializedDiffs;
    final boolean sendFullVersion;
    try {
        nodes = clusterChangedEvent.state().nodes();
        nodesToPublishTo = new HashSet<>(nodes.getSize());
        DiscoveryNode localNode = nodes.getLocalNode();
        final int totalMasterNodes = nodes.getMasterNodes().size();
        for (final DiscoveryNode node : nodes) {
            if (node.equals(localNode) == false) {
                nodesToPublishTo.add(node);
            }
        }
        sendFullVersion = !discoverySettings.getPublishDiff() || clusterChangedEvent.previousState() == null;
        serializedStates = new HashMap<>();
        serializedDiffs = new HashMap<>();
        // we build these early as a best effort not to commit in the case of error.
        // sadly this is not water tight as it may that a failed diff based publishing to a node
        // will cause a full serialization based on an older version, which may fail after the
        // change has been committed.
        buildDiffAndSerializeStates(clusterChangedEvent.state(), clusterChangedEvent.previousState(), nodesToPublishTo, sendFullVersion, serializedStates, serializedDiffs);
        final BlockingClusterStatePublishResponseHandler publishResponseHandler = new AckClusterStatePublishResponseHandler(nodesToPublishTo, ackListener);
        sendingController = new SendingController(clusterChangedEvent.state(), minMasterNodes, totalMasterNodes, publishResponseHandler);
    } catch (Exception e) {
        throw new Discovery.FailedToCommitClusterStateException("unexpected error while preparing to publish", e);
    }
    try {
        innerPublish(clusterChangedEvent, nodesToPublishTo, sendingController, sendFullVersion, serializedStates, serializedDiffs);
    } catch (Discovery.FailedToCommitClusterStateException t) {
        throw t;
    } catch (Exception e) {
        // try to fail committing, in cause it's still on going
        if (sendingController.markAsFailed("unexpected error", e)) {
            // signal the change should be rejected
            throw new Discovery.FailedToCommitClusterStateException("unexpected error", e);
        } else {
            throw e;
        }
    }
}
Also used : BytesReference(org.elasticsearch.common.bytes.BytesReference) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) Discovery(org.elasticsearch.discovery.Discovery) ElasticsearchException(org.elasticsearch.ElasticsearchException) IncompatibleClusterStateVersionException(org.elasticsearch.cluster.IncompatibleClusterStateVersionException) IOException(java.io.IOException) TransportException(org.elasticsearch.transport.TransportException) Version(org.elasticsearch.Version) BlockingClusterStatePublishResponseHandler(org.elasticsearch.discovery.BlockingClusterStatePublishResponseHandler) DiscoveryNodes(org.elasticsearch.cluster.node.DiscoveryNodes) AckClusterStatePublishResponseHandler(org.elasticsearch.discovery.AckClusterStatePublishResponseHandler)

Aggregations

DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)2 BlockingClusterStatePublishResponseHandler (org.elasticsearch.discovery.BlockingClusterStatePublishResponseHandler)2 IOException (java.io.IOException)1 ElasticsearchException (org.elasticsearch.ElasticsearchException)1 Version (org.elasticsearch.Version)1 ClusterState (org.elasticsearch.cluster.ClusterState)1 IncompatibleClusterStateVersionException (org.elasticsearch.cluster.IncompatibleClusterStateVersionException)1 DiscoveryNodes (org.elasticsearch.cluster.node.DiscoveryNodes)1 BytesReference (org.elasticsearch.common.bytes.BytesReference)1 TimeValue (org.elasticsearch.common.unit.TimeValue)1 AckClusterStatePublishResponseHandler (org.elasticsearch.discovery.AckClusterStatePublishResponseHandler)1 Discovery (org.elasticsearch.discovery.Discovery)1 TransportException (org.elasticsearch.transport.TransportException)1