/**
*
*/
package org.csc.phynixx.watchdog;
/*
* #%L
* phynixx-watchdog
* %%
* Copyright (C) 2014 csc
* %%
* 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.csc.phynixx.common.generator.IDGenerator;
import org.csc.phynixx.common.generator.IDGenerators;
import org.csc.phynixx.common.logger.IPhynixxLogger;
import org.csc.phynixx.common.logger.PhynixxLogManager;
import org.csc.phynixx.watchdog.log.ConditionViolatedLog;
/**
* this class starts both a thread and a watchdog watching itself.
* It must be explicitly killed.
* The watchdog is killed, if the C'tor parameter removeConditionOnExit is true.
* If not the registry waits to the condition to be finalized and the condition to become useless.
* Created by christoph on 09.06.2012.
*/
public class WatchdogAware extends TimeoutCondition implements Runnable, IWatchedCondition {
private static final IDGenerator<Long> ID_GENERATOR = IDGenerators.createLongGenerator(1, true);
private static long CHECK_INTERVAL = 10;
private IPhynixxLogger log = PhynixxLogManager.getLogger(this.getClass());
private long idleTime = -1l;
private volatile boolean killed = false;
private volatile byte conditionFailedCounter = 0;
private volatile boolean shutdown = false;
private IWatchdog watchdog = null;
private String id = null;
/**
* @param idleTime idle time of this runnable
* @param timeout timeout of the wachdog condition
*/
public WatchdogAware(long idleTime, long timeout) {
super(timeout);
this.idleTime = idleTime;
this.id = "WatchdogAware[" + ID_GENERATOR.generate() + "]";
}
public void kill() {
this.killed = true;
}
public boolean isKilled() {
return this.killed;
}
public long getIdleTime() {
return idleTime;
}
public IWatchdog getWatchdog() {
return watchdog;
}
public synchronized int getConditionFailedCounter() {
return new Byte(this.conditionFailedCounter).intValue();
}
public synchronized boolean isShutdown() {
return shutdown;
}
/**
* registers an Condition just counting the calls to check the it
*/
private void registerWatching() {
IWatchdog wd = WatchdogRegistry.getTheRegistry().createWatchdog(CHECK_INTERVAL);
this.setActive(true);
wd.registerCondition(this);
this.watchdog = wd;
}
/**
* registered this at an newly created watchdog
*/
public void run() {
this.killed = false;
this.registerWatching();
log.info(this.id + " started (idletime=" + idleTime + " checkInterval=" + super.getTimeout() + ")");
// System.out.println("Thread "+Thread.currentThread()+" is Killed "+ killed);
while (!this.isKilled()) {
// wait until it time to check the conditions
long start = System.currentTimeMillis();
long waiting = this.idleTime;
while (waiting > 0) {
try {
Thread.sleep(waiting);
} catch (InterruptedException e) {
} finally {
waiting = this.idleTime - (System.currentTimeMillis() - start);
}
}
// log.debug("WatchdogAware "+id+" - Thread " + Thread.currentThread()+" -- live time "+ System.currentTimeMillis()+" interval="+(System.currentTimeMillis() - start) );
}
log.info(this.id + " is killed");
this.shutdown = true;
}
protected void finalize() throws Throwable {
log.error(this.id + " is finalized");
super.finalize();
}
public void conditionViolated() {
this.resetCondition();
this.conditionFailedCounter++;
log.info(new ConditionViolatedLog(this, this.id).toString());
}
}