package com.github.drapostolos.rdp4j;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.drapostolos.rdp4j.spi.PolledDirectory;
/**
* This is the timer thread which is executed every n milliseconds
* according to the setting of the directory poller. It investigates the
* directory in question and notify listeners if files are added/removed/modified,
* or if IO Error has been raised/ceased.
*/
final class ScheduledRunnable implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(ScheduledRunnable.class);
private final DirectoryPoller dp;
private final Set<Poller> pollers = new CopyOnWriteArraySet<Poller>();
private final ListenerNotifier notifier;
private final ExecutorService executor;
ScheduledRunnable(DirectoryPoller directoryPoller) {
dp = directoryPoller;
this.notifier = dp.notifier;
for (PolledDirectory directory : dp.directories) {
pollers.add(new Poller(dp, directory));
}
if (dp.parallelDirectoryPollingEnabled) {
executor = Executors.newCachedThreadPool();
} else {
executor = Executors.newSingleThreadExecutor();
}
}
/**
* This method is periodically called by the {@link ExecutorService}.
*/
@Override
public synchronized void run() {
try {
notifier.beforePollingCycle(new BeforePollingCycleEvent(dp));
if (!executor.isShutdown()) {
executor.invokeAll(pollers);
}
notifier.afterPollingCycle(new AfterPollingCycleEvent(dp));
} catch (InterruptedException e) {
// allow thread to exit gracefully
} catch (Throwable t) {
LOG.error("Unexpected error!", t);
}
}
void addListener(Rdp4jListener listener) {
notifier.addListener(listener);
}
void removeListener(Rdp4jListener listener) {
notifier.removeListener(listener);
}
void addDirectory(PolledDirectory directory) {
pollers.add(new Poller(dp, directory));
}
void removeDirectory(PolledDirectory directory) {
pollers.remove(new Poller(dp, directory));
}
void shutdown() {
executor.shutdown();
}
void awaitTermination() {
Util.awaitTermination(executor);
}
Set<PolledDirectory> getDirectories() {
Set<PolledDirectory> result = new HashSet<PolledDirectory>();
for (Poller poller : pollers) {
result.add(poller.directory);
}
return result;
}
}