io.druid.indexing.coordinator.scaling.ResourceManagementScheduler.java Source code

Java tutorial

Introduction

Here is the source code for io.druid.indexing.coordinator.scaling.ResourceManagementScheduler.java

Source

/*
 * Druid - a distributed column store.
 * Copyright (C) 2012, 2013  Metamarkets Group Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package io.druid.indexing.coordinator.scaling;

import com.metamx.common.concurrent.ScheduledExecutors;
import com.metamx.common.lifecycle.LifecycleStart;
import com.metamx.common.lifecycle.LifecycleStop;
import com.metamx.common.logger.Logger;
import io.druid.granularity.PeriodGranularity;
import io.druid.indexing.coordinator.RemoteTaskRunner;
import io.druid.indexing.coordinator.TaskRunner;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Period;

import java.util.concurrent.ScheduledExecutorService;

/**
 * The ResourceManagementScheduler schedules a check for when worker nodes should potentially be created or destroyed.
 * It uses a {@link TaskRunner} to return all pending tasks in the system and the status of the worker nodes in
 * the system.
 * The ResourceManagementScheduler does not contain the logic to decide whether provision or termination should actually
 * occur. That decision is made in the {@link ResourceManagementStrategy}.
 */
public class ResourceManagementScheduler {
    private static final Logger log = new Logger(ResourceManagementScheduler.class);

    private final RemoteTaskRunner taskRunner;
    private final ResourceManagementStrategy resourceManagementStrategy;
    private final ResourceManagementSchedulerConfig config;
    private final ScheduledExecutorService exec;

    private final Object lock = new Object();
    private volatile boolean started = false;

    public ResourceManagementScheduler(RemoteTaskRunner taskRunner,
            ResourceManagementStrategy resourceManagementStrategy, ResourceManagementSchedulerConfig config,
            ScheduledExecutorService exec) {
        this.taskRunner = taskRunner;
        this.resourceManagementStrategy = resourceManagementStrategy;
        this.config = config;
        this.exec = exec;
    }

    @LifecycleStart
    public void start() {
        synchronized (lock) {
            if (started) {
                return;
            }

            log.info("Started Resource Management Scheduler");

            ScheduledExecutors.scheduleAtFixedRate(exec, config.getProvisionPeriod().toStandardDuration(),
                    new Runnable() {
                        @Override
                        public void run() {
                            resourceManagementStrategy.doProvision(taskRunner.getPendingTasks(),
                                    taskRunner.getWorkers());
                        }
                    });

            // Schedule termination of worker nodes periodically
            Period period = config.getTerminatePeriod();
            PeriodGranularity granularity = new PeriodGranularity(period, config.getOriginTime(), null);
            final long startTime = granularity.next(granularity.truncate(new DateTime().getMillis()));

            ScheduledExecutors.scheduleAtFixedRate(exec, new Duration(System.currentTimeMillis(), startTime),
                    config.getTerminatePeriod().toStandardDuration(), new Runnable() {
                        @Override
                        public void run() {
                            resourceManagementStrategy.doTerminate(taskRunner.getPendingTasks(),
                                    taskRunner.getWorkers());
                        }
                    });

            started = true;
        }
    }

    @LifecycleStop
    public void stop() {
        synchronized (lock) {
            if (!started) {
                return;
            }
            log.info("Stopping Resource Management Scheduler");
            exec.shutdown();
            started = false;
        }
    }

    public ScalingStats getStats() {
        return resourceManagementStrategy.getStats();
    }
}