org.voltcore.utils.EstTimeUpdater Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of voltdbclient Show documentation
Show all versions of voltdbclient Show documentation
VoltDB client interface libraries
/* 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;
}
}