io.pravega.controller.fault.SegmentContainerMonitor.java Source code

Java tutorial

Introduction

Here is the source code for io.pravega.controller.fault.SegmentContainerMonitor.java

Source

/**
 * Copyright (c) 2017 Dell Inc., or its subsidiaries. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */
package io.pravega.controller.fault;

import io.pravega.controller.store.host.HostControllerStore;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.AbstractIdleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.leader.LeaderSelector;
import org.apache.curator.utils.ZKPaths;

/**
 * Class used to monitor the pravega host cluster for failures and ensure the segment containers owned by them are
 * assigned to the other pravega hosts.
 */
@Slf4j
public class SegmentContainerMonitor extends AbstractIdleService {

    //The leader which monitors the data cluster and ensures all containers are mapped to available hosts.
    private final SegmentMonitorLeader segmentMonitorLeader;

    //The leader selector which competes with peer controller nodes. We are using this to ensure there is always only
    //one writer for the host to container map. This will prevent race conditions and also simplifies coordination
    //during load balancing.
    private final LeaderSelector leaderSelector;

    //The ZK path which is monitored for leader selection.
    private final String leaderZKPath;

    /**
     * Monitor to manage pravega host addition and removal in the cluster.
     *
     * @param hostStore             The store to read and write the host container mapping data.
     * @param client                The curator client for coordination.
     * @param balancer              The host to segment container balancer implementation.
     * @param minRebalanceInterval  The minimum interval between any two rebalance operations in seconds.
     *                              0 indicates there can be no waits between retries.
     */
    public SegmentContainerMonitor(HostControllerStore hostStore, CuratorFramework client,
            ContainerBalancer balancer, int minRebalanceInterval) {
        Preconditions.checkNotNull(hostStore, "hostStore");
        Preconditions.checkNotNull(client, "client");
        Preconditions.checkNotNull(balancer, "balancer");

        leaderZKPath = ZKPaths.makePath("cluster", "faulthandlerleader");

        segmentMonitorLeader = new SegmentMonitorLeader(hostStore, balancer, minRebalanceInterval);
        leaderSelector = new LeaderSelector(client, leaderZKPath, segmentMonitorLeader);

        //Listen for any zookeeper connectivity error and relinquish leadership.
        client.getConnectionStateListenable().addListener((curatorClient, newState) -> {
            switch (newState) {
            case LOST:
                log.warn("Connection to zookeeper lost, attempting to interrrupt the leader thread");
                leaderSelector.interruptLeadership();
                break;
            case SUSPENDED:
                if (leaderSelector.hasLeadership()) {
                    log.info("Zookeeper session suspended, pausing the segment monitor");
                    segmentMonitorLeader.suspend();
                }
                break;
            case RECONNECTED:
                if (leaderSelector.hasLeadership()) {
                    log.info("Zookeeper session reconnected, resume the segment monitor");
                    segmentMonitorLeader.resume();
                }
                break;
            //$CASES-OMITTED$
            default:
                log.debug("Connection state to zookeeper updated: " + newState.toString());
            }
        });
    }

    /**
     * Start the leader selection process.
     */
    @Override
    protected void startUp() {
        //Ensure this process always competes for leadership.
        leaderSelector.autoRequeue();
        leaderSelector.start();
    }

    /**
     * Relinquish leadership and close.
     */
    @Override
    protected void shutDown() {
        leaderSelector.interruptLeadership();
        leaderSelector.close();
    }
}