package fi.otavanopisto.muikku.plugins.schooldatapyramus.schedulers; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.ejb.Singleton; import javax.ejb.Timeout; import javax.ejb.Timer; import javax.ejb.TimerConfig; import javax.ejb.TimerService; import javax.enterprise.event.Observes; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.apache.commons.collections.IteratorUtils; import fi.otavanopisto.muikku.events.ContextDestroyedEvent; import fi.otavanopisto.muikku.events.ContextInitializedEvent; import fi.otavanopisto.muikku.plugins.schooldatapyramus.SchoolDataPyramusPluginDescriptor; @Singleton public class PyramusScheduler { private static final int INITIAL_TIMEOUT = 1000 * 180; // 180 sec private static final int TIMEOUT = 1000 * 15; // 15 sec private static final int ERROR_TIMEOUT = 1000 * 60; // 60 sec @Any @Inject private Instance<PyramusUpdateScheduler> updateSchedulers; @Resource private TimerService timerService; @Inject private Logger logger; @PostConstruct public void init() { contextInitialized = false; running = false; schedulerIndex = 0; } public void onContextInitialized(@Observes ContextInitializedEvent event) { contextInitialized = true; startTimer(INITIAL_TIMEOUT); } public void onContextDestroyed(@Observes ContextDestroyedEvent event) { contextInitialized = false; if (this.timer != null) { timer.cancel(); timer = null; } } @Timeout public void syncTimeout(Timer timer) { try { synchronizePyramusData(); startTimer(TIMEOUT); } catch (Exception ex) { logger.log(Level.SEVERE, "synchronization failed.", ex); startTimer(ERROR_TIMEOUT); } } public void synchronizePyramusData() { if (!SchoolDataPyramusPluginDescriptor.SCHEDULERS_ACTIVE) { return; } if (contextInitialized) { if (running) { return; } @SuppressWarnings("unchecked") List<PyramusUpdateScheduler> schedulers = IteratorUtils.toList(updateSchedulers.iterator()); Collections.sort(schedulers, new Comparator<PyramusUpdateScheduler>() { @Override public int compare(PyramusUpdateScheduler o1, PyramusUpdateScheduler o2) { return o1.getPriority() - o2.getPriority(); } }); PyramusUpdateScheduler updateScheduler = schedulers.get(schedulerIndex); try { running = true; updateScheduler.synchronize(); } catch (Exception ex) { logger.log(Level.SEVERE, "Synchronization failed", ex); } finally { running = false; } schedulerIndex = (schedulerIndex + 1) % schedulers.size(); } } private void startTimer(int duration) { if (!contextInitialized) return; if ("true".equals(System.getProperty("tests.running"))) { return; } if (this.timer != null) { this.timer.cancel(); this.timer = null; } TimerConfig timerConfig = new TimerConfig(); timerConfig.setPersistent(false); this.timer = timerService.createSingleActionTimer(duration, timerConfig); } private Timer timer; private boolean contextInitialized; private boolean running; private int schedulerIndex; }