/**
* HiveDB is an Open Source (LGPL) system for creating large, high-transaction-volume
* data storage systems.
*/
package org.hivedb;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
import javax.sql.DataSource;
import org.hivedb.meta.persistence.HiveBasicDataSource;
import org.hivedb.meta.persistence.HiveSemaphoreDao;
/**
* HiveSyncDaemon continually polls the hive and notifies listeners when
* the revision number increments. Listeners use this notification to reload the hive.
* The hive's revision number increase increments when any metadata of the hive changes,
* such as a new data node or secondary index. See Hive for more details.
* @author Britt Crawford
*
*/
public class HiveSyncDaemon extends Thread {
private Observable hiveStatus;
private long lastRun = 0;
private String hiveUri;
private int lastRevision = Integer.MIN_VALUE;
private int sleepPeriodMs = 5000;
@SuppressWarnings("unchecked")
public static HiveSyncDaemon startDaemon(String uri, int sleepPeriodMs, Collection observers) {
HiveSyncDaemon daemon = new HiveSyncDaemon(uri, sleepPeriodMs, observers);
daemon.start();
return daemon;
}
public HiveSyncDaemon(String uri, int sleepPeriodMs, Collection<Observer> observers) {
this(uri, observers);
this.sleepPeriodMs = sleepPeriodMs;
}
public HiveSyncDaemon(String uri, Collection<Observer> observers) {
hiveUri = uri;
hiveStatus = new HiveUpdateStatus();
for(Observer o : observers)
hiveStatus.addObserver(o);
}
private DataSource cachedDataSource = null;
private DataSource getDataSource() {
if (cachedDataSource == null) {
cachedDataSource = new HiveBasicDataSource(hiveUri);
}
return cachedDataSource;
}
private int getLatestRevision() {
return new HiveSemaphoreDao(getDataSource()).get().getRevision();
}
public synchronized void detectChanges() {
int latestRevision = getLatestRevision();
if (lastRevision != latestRevision)
hiveStatus.notifyObservers();
lastRevision = latestRevision;
}
public void run() {
while (true) {
try {
detectChanges();
lastRun = System.currentTimeMillis();
} catch (Exception e) {}
try {
sleep(getConfiguredSleepPeriodMs());
} catch (InterruptedException e) {}
}
}
/**
* Reports true if the sync thread has run within the last (2 *
* getConfiguredSleepPeriodMs()).
*/
public boolean isRunning() {
return ((System.currentTimeMillis() - lastRun) < 2 * getConfiguredSleepPeriodMs());
}
public int getConfiguredSleepPeriodMs() {
return sleepPeriodMs;
}
public void setSleepPeriodMs(int ms) {
this.sleepPeriodMs = ms;
}
class HiveUpdateStatus extends Observable {
public void notifyObservers() {
super.setChanged();
super.notifyObservers();
}
}
}