Package com.foundationdb.sql

Source Code of com.foundationdb.sql.Main

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.sql;

import com.foundationdb.server.service.config.ConfigurationService;
import com.foundationdb.server.service.servicemanager.GuicedServiceManager;
import com.foundationdb.util.GCMonitor;
import com.foundationdb.util.LoggingStream;
import com.foundationdb.util.OsUtils;
import com.google.inject.Inject;
import com.google.inject.ProvisionException;

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

import com.foundationdb.server.error.StartupFailureException;
import com.foundationdb.server.manage.ManageMXBean;
import com.foundationdb.server.manage.ManageMXBeanImpl;
import com.foundationdb.server.service.Service;
import com.foundationdb.server.service.ServiceManager;
import com.foundationdb.server.service.jmx.JmxManageable;

import javax.management.ObjectName;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.Semaphore;

public class Main implements Service, JmxManageable, LayerInfoInterface
{
    private static final Logger LOG = LoggerFactory.getLogger(Main.class);

    private static final String VERSION_PROPERTY_FILE = "/version/fdbsql_version.properties";
    public static final LayerVersionInfo VERSION_INFO;

    static {
        Properties props = new Properties();
        try(InputStream stream = Main.class.getResourceAsStream(VERSION_PROPERTY_FILE)) {
            props.load(stream);
        } catch (IOException e) {
            LOG.warn("Couldn't read version resource file: {}", VERSION_PROPERTY_FILE);
        }
        VERSION_INFO = new LayerVersionInfo(props);
    }

    private static final String NAME_PROP = "fdbsql.name";
    private static final String GC_INTERVAL_NAME = "fdbsql.gc_monitor.interval";
    private static final String GC_THRESHOLD_NAME = "fdbsql.gc_monitor.log_threshold_ms";
    private static final String PID_FILE_NAME = System.getProperty("fdbsql.pidfile");
    private static final boolean IS_STD_TO_LOG = Boolean.parseBoolean(System.getProperty("fdbsql.std_to_log", "true"));

    private static volatile ShutdownMXBeanImpl shutdownBean = null;

    private final JmxObjectInfo jmxObjectInfo;
    private final ConfigurationService config;
    private GCMonitor gcMonitor;

    @Inject
    public Main(ConfigurationService config) {
        this.config = config;
        this.jmxObjectInfo = new JmxObjectInfo(
                "SQLLAYER",
                new ManageMXBeanImpl(),
                ManageMXBean.class
        );
    }

    @Override
    public void start() {
        int interval = Integer.parseInt(config.getProperty(GC_INTERVAL_NAME));
        int logThreshold = Integer.parseInt(config.getProperty(GC_THRESHOLD_NAME));
        if(interval > 0) {
            gcMonitor = new GCMonitor(interval, logThreshold);
            gcMonitor.start();
        }
    }

    @Override
    public void stop()
    {
        if(gcMonitor != null) {
            gcMonitor.stopRunning();
            gcMonitor = null;
        }
    }
   
    @Override
    public void crash() {
        stop();
    }

    @Override
    public JmxObjectInfo getJmxObjectInfo() {
        return jmxObjectInfo;
    }

    @Override
    public String getServerName()
    {
        return config.getProperty(NAME_PROP);
    }

    @Override
    public LayerVersionInfo getVersionInfo() {
        return VERSION_INFO;
    }

    public interface ShutdownMXBean {
        public void shutdown();
    }

    private static class ShutdownMXBeanImpl implements ShutdownMXBean {
        private static final String BEAN_NAME = "com.foundationdb:type=SHUTDOWN";
        private final ServiceManager sm;

        public ShutdownMXBeanImpl(ServiceManager sm) {
            this.sm = sm;
        }

        @Override
        public void shutdown() {
            try {
                if(sm != null) {
                    sm.stopServices();
                }
            } catch (Exception e) {
                LOG.error("Problem stopping services", e);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        if(IS_STD_TO_LOG) {
            System.setErr(new PrintStream(LoggingStream.forError(LOG), true));
            System.setOut(new PrintStream(LoggingStream.forInfo(LOG), true));
        }

        try {
            doStartup();
        } catch (ProvisionException e) {
            if (e.getCause() instanceof StartupFailureException){
                LOG.error(e.getCause().getLocalizedMessage());
            } else {
                LOG.error("Provisioning exception starting system {}", e);
            }
            System.exit(1);
        } catch(Throwable t) {
            LOG.error("Problem starting system", t);
            System.exit(1);
        }

        // Services started successfully, write pid to file.
        try {
            writePid();
        } catch(IOException e) {
            LOG.warn("Problem writing pid file {}", PID_FILE_NAME, e);
            // Do not abort on error as init scripts handle this fine.
        }
    }

    private static void doStartup() throws Exception {
        final ServiceManager serviceManager = new GuicedServiceManager();

        Main.shutdownBean = new ShutdownMXBeanImpl(serviceManager);

        // JVM shutdown hook.
        // Register before startServices() so services are still brought down on startup error.
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                shutdownBean.shutdown();
            }
        }, "ShutdownHook"));

        // Bring system up
        serviceManager.startServices();

        ObjectName name = new ObjectName(ShutdownMXBeanImpl.BEAN_NAME);
        ManagementFactory.getPlatformMBeanServer().registerMBean(shutdownBean, name);
    }

    private static void writePid() throws IOException {
        if (PID_FILE_NAME != null) {
            File pidFile = new File(PID_FILE_NAME);
            pidFile.deleteOnExit();
            FileWriter out = new FileWriter(pidFile);
            out.write(OsUtils.getProcessID());
            out.flush();
            out.close();
        }
    }


    /**
     * Start from procrun.
     * @see <a href="http://commons.apache.org/daemon/procrun.html">Daemon: Procrun</a>
     */
    private static final Semaphore PROCRUN_SEMAPHORE = new Semaphore(0);

    private static boolean isProcrunJVMMode(String[] args) {
        if(args.length != 1) {
            String message = "Expected exactly one argument (StartMode)";
            LOG.error("{}: {}", message, Arrays.toString(args));
            throw new IllegalArgumentException(message);
        }
        return "jvm".equals(args[0]);
    }

    @SuppressWarnings("unused") // Called by procrun
    public static void procrunStart(String[] args) throws Exception {
        boolean jvmMode = isProcrunJVMMode(args);
        main(args);
        if(jvmMode) {
            PROCRUN_SEMAPHORE.acquire();
        }
    }

    @SuppressWarnings("unused") // Called by procrun
    public static void procrunStop(String[] args) throws Exception {
        boolean jvmMode = isProcrunJVMMode(args);
        // Stop server from another thread.
        shutdownBean.shutdown();
        if(jvmMode) {
            PROCRUN_SEMAPHORE.release();
        }
    }
}
TOP

Related Classes of com.foundationdb.sql.Main

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.