added waitUntilNotLoading to TrackedRace and use it in the expensive caches to avoid recomputatoins during loading phase

This commit is contained in:
Axel Uhl committed 2013-01-26 18:00:42 +01:00
1 parent 4a580983d5
commit 548c80836e
5 files changed
+52 -5

No files matched your search

@@ -718,6 +718,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
@Override
public void setStatus(TrackedRaceStatus newStatus) {
// TODO Auto-generated method stub
}
@Override
public void waitUntilNotLoading() {
// TODO Auto-generated method stub
}
}
@@ -456,13 +456,11 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
@Override
public void lockForRead(Iterable<MarkPassing> markPassings) {
// TODO Auto-generated method stub
}
@Override
public void unlockAfterRead(Iterable<MarkPassing> markPassings) {
// TODO Auto-generated method stub
}
@Override
@@ -470,4 +468,9 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
// TODO Auto-generated method stub
return null;
}
@Override
public void waitUntilNotLoading() {
// TODO Auto-generated method stub
}
}
@@ -452,4 +452,10 @@ public interface TrackedRace extends Serializable {
void waitUntilWindLoadingComplete() throws InterruptedException;
TrackedRaceStatus getStatus();
/**
* If the {@link #getStatus() status} is currently {@link TrackedRaceStatus.Status#LOADING}, blocks until the status changes to any
* other status.
*/
void waitUntilNotLoading();
}
@@ -398,6 +398,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
public void run() {
// no locking required here; the incremental cache refresh protects the inner cache structures from concurrent modifications
cacheInvalidationTimer.cancel(); // terminates the timer thread
getTrackedRace().waitUntilNotLoading();
refreshCacheIncrementally();
}
}, delayForCacheInvalidationInMilliseconds);
@@ -506,7 +507,8 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
@Override
public void statusChanged(TrackedRaceStatus newStatus) {
// TODO bug 1175: block recomputation in LOADING state, unblock them when changing state away from LOADING
// If the status changes from LOADING to something else, the waitUntilNotLoading call in the scheduler's
// run() method will be unblocked. Therefore no action is required here.
}
@Override
@@ -106,6 +106,8 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
private final TrackedRegatta trackedRegatta;
private TrackedRaceStatus status;
private final Object statusNotifier;
/**
* By default, all wind sources are used, none are excluded. However, e.g., for performance reasons, particular wind
@@ -251,6 +253,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
super();
locksForMarkPassings = new IdentityHashMap<>();
this.status = new TrackedRaceStatusImpl(Status.PREPARED, 0.0);
this.statusNotifier = new Object[0];
this.serializationLock = new NamedReentrantReadWriteLock("Serialization lock for tracked race "+race.getName(), /* fair */ true);
this.cacheInvalidationTimerLock = new Object();
this.updateCount = 0;
@@ -376,6 +379,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
@Override
public Triple<TimePoint, TimePoint, List<Maneuver>> computeCacheUpdate(Competitor competitor,
EmptyUpdateInterval updateInterval) throws NoWindException {
waitUntilNotLoading();
return computeManeuvers(competitor);
}
}, /* nameForLocks */ "Maneuver cache for race "+getRace().getName());
@@ -2202,7 +2206,35 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
return status;
}
/**
* Changes to the {@link #status} variable are synchronized on the {@link #statusNotifier} field.
* @return
*/
protected Object getStatusNotifier() {
return statusNotifier;
}
protected void setStatus(TrackedRaceStatus newStatus) {
this.status = newStatus;
synchronized (getStatusNotifier()) {
this.status = newStatus;
getStatusNotifier().notifyAll();
}
}
/**
* Waits on the current ("old") status object which is notified in {@link #setStatus(TrackedRaceStatus)} when the status
* is changed. The change as well as the check synchronize on the old status object.
*/
@Override
public void waitUntilNotLoading() {
synchronized (getStatusNotifier()) {
while (getStatus().getStatus() == Status.LOADING) {
try {
getStatusNotifier().wait();
} catch (InterruptedException e) {
logger.info("waitUntilNotLoading on tracked race "+this+" interrupted: "+e.getMessage()+". Continuing to wait.");
}
}
}
}
}