All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.dynomitemanager.FloridaServer Maven / Gradle / Ivy

There is a newer version: 2.0.36
Show newest version
/**
 * Copyright 2013 Netflix, Inc.
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.netflix.dynomitemanager;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.netflix.dynomitemanager.backup.RestoreTask;
import com.netflix.dynomitemanager.backup.SnapshotTask;
import com.netflix.dynomitemanager.config.FloridaConfig;
import com.netflix.dynomitemanager.config.InstanceState;
import com.netflix.dynomitemanager.dynomite.DynomiteProcessManager;
import com.netflix.dynomitemanager.dynomite.DynomiteYamlTask;
import com.netflix.dynomitemanager.dynomite.IDynomiteProcess;
import com.netflix.dynomitemanager.dynomite.ProxyAndStorageResetTask;
import com.netflix.dynomitemanager.monitoring.ProcessMonitorTask;
import com.netflix.dynomitemanager.monitoring.RedisInfoMetricsTask;
import com.netflix.dynomitemanager.monitoring.ServoMetricsTask;
import com.netflix.dynomitemanager.storage.*;
import com.netflix.nfsidecar.aws.UpdateSecuritySettings;
import com.netflix.nfsidecar.config.CommonConfig;
import com.netflix.nfsidecar.identity.InstanceIdentity;
import com.netflix.nfsidecar.scheduler.TaskScheduler;
import com.netflix.nfsidecar.utils.Sleeper;
import com.netflix.servo.DefaultMonitorRegistry;
import com.netflix.servo.monitor.Monitors;

/**
 * Start all tasks here - Property update task - Backup task - Restore task -
 * Incremental backup
 */
@Singleton
public class FloridaServer {
    private final TaskScheduler scheduler;
    private final FloridaConfig floridaConfig;
    private final CommonConfig commonConfig;
    private final InstanceIdentity id;
    private final Sleeper sleeper;
    private final DynomiteYamlTask tuneTask;
    private final IDynomiteProcess dynProcess;
    private final InstanceState state;
    private final StorageProcessManager storageProcess;
    private final StorageProxy storageProxy;
    private static final Logger logger = LoggerFactory.getLogger(FloridaServer.class);

    @Inject
    public FloridaServer(FloridaConfig floridaConfig, CommonConfig commonConfig, TaskScheduler scheduler,
            InstanceIdentity id, Sleeper sleeper, DynomiteYamlTask tuneTask, InstanceState state,
            IDynomiteProcess dynProcess, StorageProcessManager storageProcess, StorageProxy storageProxy) {
        this.floridaConfig = floridaConfig;
        this.commonConfig = commonConfig;
        this.scheduler = scheduler;
        this.id = id;
        this.sleeper = sleeper;
        this.tuneTask = tuneTask;
        this.state = state;
        this.dynProcess = dynProcess;
        this.storageProcess = storageProcess;
        this.storageProxy = storageProxy;
        try {
            initialize();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        DefaultMonitorRegistry.getInstance().register(Monitors.newObjectMonitor(state));
    }

    public void initialize() throws Exception {
        if (id.getInstance().isOutOfService()) {
            logger.error("Out of service");
            return;
        }

        logger.info("Initializing Florida Server now ...");

        state.setSideCarProcessAlive(true);
        state.setBootstrapStatus(Bootstrap.NOT_STARTED);
        state.setStorageAlive(storageProxy.isAlive());

        if (floridaConfig.isDynomiteMultiDC()) {
            scheduler.runTaskNow(UpdateSecuritySettings.class);
            /*
             * sleep for some random between 100 - 200 sec if this is a new node
             * with new IP for SG to be updated by other seed nodes
             */
            if (id.isReplace() || id.isTokenPregenerated()) {
                long initTime = 100 + (int) (Math.random() * ((200 - 100) + 1));

                logger.info("Sleeping " + initTime + " seconds -> a node is replaced or token is pregenerated.");
                sleeper.sleep(initTime * 1000);
            } else if (UpdateSecuritySettings.firstTimeUpdated) {
                logger.info("Sleeping 60 seconds -> first time security settings are updated");
                sleeper.sleep(60 * 1000);
            }

            scheduler.addTask(UpdateSecuritySettings.JOBNAME, UpdateSecuritySettings.class,
                    UpdateSecuritySettings.getTimer(id));
        }

        // Invoking the task directly as any errors in this task
        // should not let Florida continue. However, we don't want to kill
        // the Florida process, but, want it to be stuck.
        logger.info("Running TuneTask and updating configuration.");
        try {
            tuneTask.execute();
        } catch (IOException e) {
            logger.error("Cannot update Dynomite YAML " + e.getMessage());
        }

        // Determine if we need to restore from backup else start Dynomite.
        if (commonConfig.isRestoreEnabled()) {
            logger.info("Restore is enabled.");
            scheduler.runTaskNow(RestoreTask.class); // restore from the AWS
            logger.info("Scheduled task " + RestoreTask.TaskName);
        } else { // no restores needed
            logger.info("Restore is disabled.");

            /**
             * Bootstrapping cases 1. The user has enforced warm up through an
             * FP 2. It is a new node that replaces an existing token (node
             * termination) 3. An existing token exists and Storage is not alive
             * (node reboot)
             */
            boolean warmUp = false;
            if (floridaConfig.isForceWarm()) {
                logger.info("force bootstrap -> warm up");
                warmUp = true;
            } else if (floridaConfig.isWarmBootstrap() && id.isReplace()) {
                logger.info("Instance replacement -> warm up");
                warmUp = true;
            } else if (floridaConfig.isWarmBootstrap() && !id.isNewToken() && !storageProxy.isAlive()) {
                logger.info("Not a new token and Storage is down -> warm up");
                warmUp = true;
            }

            if (warmUp) {
                logger.info("Warm bootstraping node. Scheduling BootstrapTask now!");
                dynProcess.stop();
                scheduler.runTaskNow(WarmBootstrapTask.class);
            } else {
                logger.info("Cold bootstraping, launching storage process.");
                storageProcess.start();
                sleeper.sleepQuietly(2000); // 2s
                logger.info("Launching dynomite process.");
                dynProcess.start();
                sleeper.sleepQuietly(1000); // 1s
                scheduler.runTaskNow(ProxyAndStorageResetTask.class);
            }
        }

        // Backup
        if (commonConfig.isBackupEnabled() && commonConfig.getBackupHour() >= 0) {
            scheduler.addTask(SnapshotTask.TaskName, SnapshotTask.class, SnapshotTask.getTimer(commonConfig));
        }

        // Metrics
        scheduler.addTask(ServoMetricsTask.TaskName, ServoMetricsTask.class, ServoMetricsTask.getTimer());
        scheduler.addTask(RedisInfoMetricsTask.TaskName, RedisInfoMetricsTask.class, RedisInfoMetricsTask.getTimer());

        // Routine monitoring and restarting dynomite or storage processes as
        // needed.
        scheduler.addTask(ProcessMonitorTask.JOBNAME, ProcessMonitorTask.class, ProcessMonitorTask.getTimer());
        scheduler.addTask(DynomiteProcessManager.JOB_TASK_NAME, DynomiteProcessManager.class,
                DynomiteProcessManager.getTimer());

        scheduler.addTask(RedisStorageProxy.JOB_TASK_NAME, RedisStorageProxy.class, RedisStorageProxy.getTimer());

        // Routing changing the YML file so that a manual Dynomite restart gets
        // the proper tokens
        scheduler.addTask(DynomiteYamlTask.JOBNAME, DynomiteYamlTask.class, DynomiteYamlTask.getTimer());

        logger.info("Starting task scheduler");
        scheduler.start();
    }

    public InstanceIdentity getId() {
        return id;
    }

    public TaskScheduler getScheduler() {
        return scheduler;
    }

    public FloridaConfig getConfiguration() {
        return floridaConfig;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy