package nl.topicus.onderwijs.dashboard.timers; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import nl.topicus.onderwijs.dashboard.modules.DashboardRepository; import nl.topicus.onderwijs.dashboard.modules.ServiceConfiguration; import nl.topicus.onderwijs.dashboard.modules.topicus.Retriever; import nl.topicus.onderwijs.dashboard.web.DashboardMode; import nl.topicus.onderwijs.dashboard.web.WicketApplication; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Updater implements InitializingBean { private static final Logger log = LoggerFactory.getLogger(Updater.class); private boolean enabled = false; private ScheduledExecutorService timer; @Autowired private WicketApplication application; @Autowired private List<Retriever> retrievers; @Autowired @Resource(name = "random") private DashboardRepository repository; public Updater() { } @Override public void afterPropertiesSet() { for (Retriever curRetriever : retrievers) { curRetriever.onConfigure(repository); } } public synchronized void restart() { stop(); if (!isEnabled()) { enabled = true; timer = Executors.newScheduledThreadPool(4); log.info("(Re)scheduling timer tasks"); for (Retriever curRetriever : retrievers) { ServiceConfiguration config = curRetriever.getClass() .getAnnotation(ServiceConfiguration.class); if (config.runInRandomMode() || application.getMode() == DashboardMode.LiveData) { timer.scheduleWithFixedDelay(new TimerTask(curRetriever), 0, config.interval(), config.unit()); } } } } public synchronized void stop() { if (isEnabled()) { enabled = false; log.info("Stopping timer task"); timer.shutdownNow(); try { boolean terminated = timer.awaitTermination(10, TimeUnit.SECONDS); if (!terminated) { log .error("Failed to terminate the timer within 10 seconds"); } } catch (InterruptedException e) { log.info("Terminating the timer was interrupted", e); } } } class TimerTask implements Runnable { private Retriever retriever; public TimerTask(Retriever retriever) { this.retriever = retriever; } @Override public void run() { try { if (isEnabled() && !application.isShuttingDown()) { log.info("Starting refresh for " + retriever.getClass().getSimpleName()); retriever.refreshData(); log.info("Refresh completed for " + retriever.getClass().getSimpleName()); } } catch (Exception e) { e.printStackTrace(); log.error("Uncaught exception during update task " + retriever.getClass().getSimpleName() + ": " + e.getClass().getSimpleName() + ": " + e.getMessage()); } } } private boolean isEnabled() { return enabled; } }