diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java
index d6391b1df5d..ebf802e463a 100644
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java
@@ -245,5 +245,5 @@ public interface Leaderboard extends Named {
* For this leaderboard computes the delay to live of the {@link TrackedRace} linked to any of the leaderboard's
* columns that has the latest start date. If no tracked race is linked to the leaderboard, null is returned.
*/
- long getDelayToLiveInMillis();
+ Long getDelayToLiveInMillis();
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java
index 41d5bf6b282..b15e99e4eb7 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java
@@ -509,7 +509,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
}
@Override
- public long getDelayToLiveInMillis() {
+ public Long getDelayToLiveInMillis() {
TimePoint startOfLatestRace = null;
Long delayToLiveInMillisForLatestRace = null;
for (RaceColumn raceColumn : getRaceColumns()) {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/LiveLeaderboardUpdater.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/LiveLeaderboardUpdater.java
index 8d0988d4572..b0e7ea12467 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/LiveLeaderboardUpdater.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/LiveLeaderboardUpdater.java
@@ -45,6 +45,12 @@ public class LiveLeaderboardUpdater implements Runnable {
*/
private static final long UPDATE_TIMEOUT_IN_MILLIS = 60000l;
+ /**
+ * A kind of "throttle"; if leaderboard updates are computed in less than this time, don't start a new update before this time has
+ * passed since starting the last update.
+ */
+ private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000l;
+
private final String leaderboardName;
private final SailingServiceImpl sailingService;
@@ -103,7 +109,7 @@ public class LiveLeaderboardUpdater implements Runnable {
TimePoint timePoint = now.minus(getLeaderboard().getDelayToLiveInMillis());
LeaderboardDTO result = null;
synchronized (this) {
- if (columnNamesForWhichCurrentLiveLeaderboardHasTheDetails.containsAll(namesOfRaceColumnsForWhichToLoadLegDetails)) {
+ if (running && columnNamesForWhichCurrentLiveLeaderboardHasTheDetails.containsAll(namesOfRaceColumnsForWhichToLoadLegDetails)) {
result = currentLiveLeaderboard;
lastRequest = timePoint;
if (result != null) {
@@ -171,8 +177,12 @@ public class LiveLeaderboardUpdater implements Runnable {
@Override
public void run() {
assert running;
- TimePoint timePoint = MillisecondsTimePoint.now().minus(getLeaderboard().getDelayToLiveInMillis());
+ logger.info("Starting "+LiveLeaderboardUpdater.class.getSimpleName()+" thread for leaderboard "+leaderboardName);
+ MillisecondsTimePoint now = MillisecondsTimePoint.now();
+ TimePoint timePoint = now.minus(getLeaderboard().getDelayToLiveInMillis());
+ TimePoint timeLastUpdateWasStarted;
while (running) {
+ timeLastUpdateWasStarted = now;
try {
final Set namesOfRaceColumnsForWhichToLoadLegDetails = getColumnNamesForWhichToFetchDetails(timePoint);
LeaderboardDTO newCacheValue = sailingService.computeLeaderboardByName(leaderboardName, timePoint,
@@ -187,14 +197,24 @@ public class LiveLeaderboardUpdater implements Runnable {
logger.throwing(LiveLeaderboardUpdater.class.getName(), "run", e1);
}
}
- timePoint = MillisecondsTimePoint.now().minus(getLeaderboard().getDelayToLiveInMillis());
+ now = MillisecondsTimePoint.now();
+ timePoint = now.minus(getLeaderboard().getDelayToLiveInMillis());
synchronized (this) {
if (timePoint.asMillis() - lastRequest.asMillis() >= UPDATE_TIMEOUT_IN_MILLIS) {
running = false;
break; // make sure no-one sets running to true again while outside the synchronized block and before re-evaluating the while condition
}
}
+ long millisToSleep = MINIMUM_TIME_BETWEEN_UPDATES - (now.asMillis()-timeLastUpdateWasStarted.asMillis());
+ if (millisToSleep > 0) {
+ try {
+ Thread.sleep(millisToSleep);
+ } catch (InterruptedException e) {
+ logger.throwing(LiveLeaderboardUpdater.class.getName(), "run", e);
+ }
+ }
}
+ logger.info(""+LiveLeaderboardUpdater.class.getSimpleName()+" thread for leaderboard "+leaderboardName+" ending");
}
/**