/*
* Copyright 2012 LinkedIn Corp.
*
* 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 azkaban.metric;
import java.util.Timer;
import java.util.TimerTask;
/**
* Metrics tracked after every interval using timer
* @param <T> Type of Value of a given metric
*/
public abstract class TimeBasedReportingMetric<T> extends AbstractMetric<T> {
private Timer timer;
protected long MAX_MILISEC_INTERVAL = 60 * 60 * 1000;
protected long MIN_MILISEC_INTERVAL = 3 * 1000;
/**
* @param metricName Name of metric
* @param metricType Metric type. For display purposes.
* @param initialValue Initial Value of a metric
* @param manager Metric Manager whom a metric will report to
* @param interval Time interval for metric tracking
* @throws MetricException
*/
public TimeBasedReportingMetric(String metricName, String metricType, T initialValue, MetricReportManager manager,
long interval) throws MetricException {
super(metricName, metricType, initialValue, manager);
if(!isValidInterval(interval)) {
throw new MetricException("Invalid interval: Cannot instantiate timer");
}
timer = new Timer();
timer.schedule(getTimerTask(), interval, interval);
}
/**
* Get a TimerTask to reschedule Timer
* @return An anonymous TimerTask class
*/
private TimerTask getTimerTask() {
final TimeBasedReportingMetric<T> lockObject = this;
TimerTask recurringReporting = new TimerTask() {
@Override
public void run() {
synchronized (lockObject) {
preTrackingEventMethod();
notifyManager();
postTrackingEventMethod();
}
}
};
return recurringReporting;
}
/**
* Method to change tracking interval
* @param interval
* @throws MetricException
*/
public void updateInterval(final long interval) throws MetricException {
if(!isValidInterval(interval)) {
throw new MetricException("Invalid interval: Cannot update timer");
}
logger.debug(String.format("Updating tracking interval to %d milisecond for %s metric", interval, getName()));
timer.cancel();
timer = new Timer();
timer.schedule(getTimerTask(), interval, interval);
}
private boolean isValidInterval(final long interval) {
return interval >= MIN_MILISEC_INTERVAL && interval <= MAX_MILISEC_INTERVAL;
}
/**
* This method is responsible for making any last minute update to value, if any
*/
protected abstract void preTrackingEventMethod();
/**
* This method is responsible for making any post processing after tracking
*/
protected abstract void postTrackingEventMethod();
}