org.opentripplanner.updater.PollingGraphUpdater Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
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;
}
}