
com.splout.db.common.HeartBeater Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of splout-hadoop Show documentation
Show all versions of splout-hadoop Show documentation
Splout is a read only, horizontally scalable SQL database that plays well with Hadoop.
package com.splout.db.common;
/*
* #%L
* Splout SQL Hadoop library
* %%
* Copyright (C) 2012 Datasalt Systems S.L.
* %%
* 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.
* #L%
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.mapreduce.TaskInputOutputContext;
import org.apache.hadoop.util.Progressable;
/**
* A Heart Beater mostly inspired by the one in SolrOutputFormat PATCH
*/
public class HeartBeater extends Thread {
public static Log LOG = LogFactory.getLog(HeartBeater.class);
/**
* count of threads asking for heart beat, at 0 no heart beat done. This could be an atomic long but then missmatches
* in need/cancel could result in negative counts.
*/
volatile int threadsNeedingHeartBeat = 0;
Progressable progress;
public final static String WAIT_TIME_CONF = "com.splout.hearbeater.wait.time";
/**
* The amount of time to wait between checks for the need to issue a heart beat. In milliseconds.
*/
long waitTimeMs;
public Progressable getProgress() {
return progress;
}
/**
* Create the heart beat object thread set it to daemon priority and start the thread. When the count in
* {@link #threadsNeedingHeartBeat} is positive, the heart beat will be issued on the progress object ever 5 seconds.
*/
public HeartBeater(Progressable progress, long waitTimeMs) {
setDaemon(true);
this.progress = progress;
this.waitTimeMs = waitTimeMs;
LOG.info("Heart beat reporting class is " + progress.getClass().getName());
start();
}
public void setProgress(Progressable progress) {
this.progress = progress;
}
@Override
public void run() {
LOG.info("HeartBeat thread running");
while(true) {
try {
synchronized(this) {
if(threadsNeedingHeartBeat > 0) {
progress.progress();
if(LOG.isInfoEnabled()) {
LOG.info(String.format("Issuing heart beat for %d threads", threadsNeedingHeartBeat));
}
} else {
if(LOG.isInfoEnabled()) {
LOG.info(String.format("heartbeat skipped count %d", threadsNeedingHeartBeat));
}
}
this.wait(waitTimeMs);
}
} catch(Throwable e) {
LOG.error("HeartBeat throwable", e);
}
}
}
/**
* inform the background thread that heartbeats are to be issued. Issue a heart beat also
*/
public synchronized void needHeartBeat() {
threadsNeedingHeartBeat++;
// Issue a progress report right away,
// just in case the the cancel comes before the background thread issues a
// report.
// If enough cases like this happen the 600 second timeout can occur
progress.progress();
if(threadsNeedingHeartBeat == 1) {
// this.notify(); // wake up the heartbeater
}
}
/**
* inform the background thread that this heartbeat request is not needed. This must be called at some point after
* each {@link #needHeartBeat()} request.
*/
public synchronized void cancelHeartBeat() {
if(threadsNeedingHeartBeat > 0) {
threadsNeedingHeartBeat--;
}
}
@SuppressWarnings("rawtypes")
public void setStatus(String status) {
if(progress instanceof TaskInputOutputContext) {
((TaskInputOutputContext) progress).setStatus(status);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy