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

org.voltcore.utils.EstTimeUpdater Maven / Gradle / Ivy

There is a newer version: 13.3.2-preview1
Show newest version
/* This file is part of VoltDB.
 * Copyright (C) 2008-2017 VoltDB Inc.
 *
 * 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 VoltDB.  If not, see .
 */

package org.voltcore.utils;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import org.voltcore.logging.VoltLogger;

public class EstTimeUpdater {
    //Report inconsistent update frequency at most every sixty seconds
    public static final long maxErrorReportInterval = 60 * 1000;
    public static long lastErrorReport = System.currentTimeMillis() - maxErrorReportInterval;

    public static final int ESTIMATED_TIME_UPDATE_FREQUENCY = Integer.getInteger("ESTIMATED_TIME_UPDATE_FREQUENCY", 5);
    public static final int ESTIMATED_TIME_WARN_INTERVAL = Integer.getInteger("ESTIMATED_TIME_WARN_INTERVAL", 2000);

    public static volatile boolean pause = false;
    public static final AtomicBoolean done = new AtomicBoolean(true);

    private final static Runnable updaterRunnable = new Runnable() {
        @Override
        public void run() {
            EstTimeUpdater.update(System.currentTimeMillis());
            while (true) {
                try {
                    Thread.sleep(ESTIMATED_TIME_UPDATE_FREQUENCY);
                } catch (InterruptedException e) {
                    if (done.get()) {
                        EstTimeUpdater.update(Long.MIN_VALUE);
                        return;
                    }
                }
                if (pause) continue;
                Long delta = EstTimeUpdater.update(System.currentTimeMillis());
                if ( delta != null ) {
                    new VoltLogger("HOST").info(delta +" estimated time update.");
                }
            }
        }
    };

    private static final AtomicReference updater = new AtomicReference<>();

    public static synchronized void stop() {
        if (done.compareAndSet(false, true)) {
            Thread updaterThread = updater.get();
            if (updater.compareAndSet(updaterThread, null)) {
                updaterThread.interrupt();
                try {
                    updaterThread.join();
                } catch (InterruptedException e) {
                }
            }
        }
    }

    public static synchronized void start() {
        if (done.compareAndSet(true, false)) {
            if (updater.compareAndSet(null, new Thread(updaterRunnable))) {
                updater.get().setDaemon(true);
                updater.get().setName("Estimated Time Updater");
                updater.get().start();
            }
        }
    }

    /**
     * Don't call this unless you have paused the updater and intend to update yourself
     * @param now
     * @return
     */
    public static Long update(final long now) {
        final long estNow = EstTime.m_now;
        if (estNow == now) {
            return null;
        }

        EstTime.m_now = now;

        /*
         * Check if updating the estimated time was especially tardy.
         * I am concerned that the thread responsible for updating the estimated
         * time might be blocking on something and want to be able to log if
         * that happens
         */
        if (now - estNow > ESTIMATED_TIME_WARN_INTERVAL) {
            /*
             * Only report the error every 60 seconds to cut down on log spam
             */
            if (lastErrorReport > now) {
                //Time moves backwards on occasion, check and reset
                lastErrorReport = now;
            }
            if (now - lastErrorReport > maxErrorReportInterval) {
                lastErrorReport = now;
                return now - estNow;
            }
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy