
org.opentripplanner.updater.PollingGraphUpdater Maven / Gradle / Ivy
package org.opentripplanner.updater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This abstract class implements logic that is shared between all polling updaters.
* Usage example ('polling' name is an example and 'polling-updater' should be the type of a
* concrete class derived from this abstract class):
*
*
* polling.type = polling-updater
* polling.frequencySec = 60
*
*
* @see GraphUpdater
*/
public abstract class PollingGraphUpdater implements GraphUpdater {
private static final Logger LOG = LoggerFactory.getLogger(PollingGraphUpdater.class);
/**
* Mirrors GraphUpdater.run method. Only difference is that runPolling will be run multiple
* times with pauses in between. The length of the pause is defined in the preference
* frequencySec.
*/
abstract protected void runPolling() throws Exception;
/** How long to wait after polling to poll again. */
protected Integer pollingPeriodSeconds;
// TODO OTP2 eliminate this field for reasons in "primed" javadoc; also "initialized" is not a clear term.
protected boolean blockReadinessUntilInitialized;
/**
* True when a full batch of realtime data has been fetched and applied to the graph.
* There was previously a second boolean field that controlled whether this affected "readiness". If we are waiting
* for any realtime data to be applied, we should wait for all of it to be applied, so I removed that.
*/
protected boolean primed;
private final String configRef;
/** Shared configuration code for all polling graph updaters. */
public PollingGraphUpdater(PollingGraphUpdaterParameters config) {
this.pollingPeriodSeconds = config.getFrequencySec();
this.configRef = config.getConfigRef();
}
@Override
final public void run() {
try {
LOG.info("Polling updater started: {}", this);
while (true) {
try {
// Run concrete polling graph updater's implementation method.
runPolling();
if (pollingPeriodSeconds <= 0) {
// Non-positive polling period values mean to run the updater only once.
LOG.info("As requested in configuration, updater {} has run only once and will now stop.",
this.getClass().getSimpleName());
break;
}
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
LOG.error("Error while running polling updater of type {}", configRef, e);
// TODO Should we cancel the task? Or after n consecutive failures? cancel();
} finally {
primed = true;
}
Thread.sleep(pollingPeriodSeconds * 1000);
}
} catch (InterruptedException e) {
// When updater is interrupted
LOG.error("Polling updater {} was interrupted and is stopping.", this.getClass().getName());
}
}
/**
* Allow clients to wait for all realtime data to be loaded before submitting any travel plan requests.
* This does not block use of the OTP server. The client must voluntarily hit an endpoint and wait for readiness.
* TODO OTP2 This is really a bit backward. We should just run() the updaters once before scheduling them to poll,
* and not bring the router online until they have finished.
*/
public boolean isPrimed () {
return primed;
}
public String getConfigRef() {
return configRef;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy