bug 4262: introduced new status REMOVED which then won't trigger cache updates;

not yet all done, particularly RaceLog tracking needs a closer look
because race/tracker removal there is a bit more complicated

Change-Id: I5fb6decf282f5465c2b5af4a9aac7e1fce15331d
This commit is contained in:
Axel Uhl committed 2017-09-15 17:02:43 +02:00
1 parent 76142a145d
commit 3b5b8bfd9f
15 files changed
+47 -28

No files matched your search

@@ -1,6 +1,6 @@
package com.sap.sailing.domain.common;
public enum TrackedRaceStatusEnum { PREPARED(0), LOADING(1), TRACKING(2), FINISHED(3), ERROR(4);
public enum TrackedRaceStatusEnum { PREPARED(0), LOADING(1), TRACKING(2), FINISHED(3), ERROR(4), REMOVED(5);
private final int order;
@@ -161,7 +161,7 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
}
@Override
protected void onStop(boolean preemptive) {
protected void onStop(boolean preemptive, boolean willBeRemoved) {
RaceLog raceLog = params.getRaceLog();
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = new TrackingTimesFinder(raceLog).analyze();
if (!trackedRegatta.getRegatta().isControlTrackingFromStartAndFinishTimes() &&
@@ -102,7 +102,7 @@ public class RegattaLogFixTrackerRegattaListener extends AbstractTrackedRegattaA
}
private void removeRaceLogSensorDataTracker(RegattaAndRaceIdentifier raceIdentifier) {
removeRaceLogSensorDataTracker(raceIdentifier, false);
removeRaceLogSensorDataTracker(raceIdentifier, /* preemptive */ false);
}
private void removeRaceLogSensorDataTracker(RegattaAndRaceIdentifier raceIdentifier, boolean preemptive) {
@@ -166,9 +166,9 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
}
@Override
protected void onStop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException {
protected void onStop(boolean preemptive, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException {
if (isTrackedRaceStillReachable()) {
TrackedRaceStatus newStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.FINISHED, 1.0);
TrackedRaceStatus newStatus = new TrackedRaceStatusImpl(willBeRemoved ? TrackedRaceStatusEnum.REMOVED : TrackedRaceStatusEnum.FINISHED, 1.0);
trackedRace.onStatusChanged(this, newStatus);
}
connector.removeSailMasterListener(this);
@@ -533,7 +533,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
}
@Override
protected void onStop(boolean stopReceiversPreemtively) throws InterruptedException {
protected void onStop(boolean stopReceiversPreemtively, boolean willBeRemoved) throws InterruptedException {
if (!stopped) {
stopped = true;
eventSubscriber.unsubscribeRaces(racesListener);
@@ -553,13 +553,13 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
new AbstractLoadingQueueDoneCallBack(receivers) {
@Override
protected void executeWhenAllReceiversAreDoneLoading() {
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.FINISHED, /* will be ignored */1.0);
lastStatus = new TrackedRaceStatusImpl(willBeRemoved ? TrackedRaceStatusEnum.REMOVED : TrackedRaceStatusEnum.FINISHED, /* will be ignored */1.0);
updateStatusOfTrackedRaces();
}
};
} else {
// queues contents were cleared preemptively; this means we're done with loading immediately
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.FINISHED, /* will be ignored */1.0);
lastStatus = new TrackedRaceStatusImpl(willBeRemoved ? TrackedRaceStatusEnum.REMOVED : TrackedRaceStatusEnum.FINISHED, /* will be ignored */1.0);
updateStatusOfTrackedRaces();
}
if (stopReceiversPreemtively && simulator != null) {
@@ -29,17 +29,26 @@ public abstract class AbstractRaceTrackerBaseImpl implements RaceTracker {
*/
@Override
public final void stop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException {
this.onStop(preemptive, /* willBeRemoved */ false);
}
/**
* Ensure stop method does notify all listeners after tracker stopped.
*/
@Override
public final void stop(boolean preemptive, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException {
try {
listeners.onTrackerWillStop(preemptive);
} finally {
onStop(preemptive);
onStop(preemptive, /* willBeRemoved */ willBeRemoved);
}
}
/**
* Template stop method for subclasses.
* @param willBeRemoved TODO
*/
protected void onStop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException {
protected void onStop(boolean preemptive, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException {
}
@Override
@@ -52,6 +52,15 @@ public interface RaceTracker {
*/
void stop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException;
/**
* Like {@link #stop(boolean)}, only that with this method the caller can assert by setting {@code willBeRemoved} to
* {@code true} that the race will be removed and no longer be accessible to clients after stopping this tracker.
* This helps save computational efforts because calculations that would otherwise be triggered when loading a race
* completes no longer need to be triggered.
*/
void stop(boolean preemptive, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException;
com.sap.sailing.domain.base.Regatta getRegatta();
/**
@@ -250,7 +250,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
}
private void updateLoaderStatus(TrackingDataLoader loader, TrackedRaceStatus status) {
if (status.getStatus() == TrackedRaceStatusEnum.FINISHED) {
if (status.getStatus() == TrackedRaceStatusEnum.FINISHED || status.getStatus() == TrackedRaceStatusEnum.REMOVED) {
loaderStatus.remove(loader);
} else {
loaderStatus.put(loader, status);
@@ -689,7 +689,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl {
@Override
public void statusChanged(TrackedRaceStatus newStatus, TrackedRaceStatus oldStatus) {
if (oldStatus.getStatus() == TrackedRaceStatusEnum.LOADING) {
if (newStatus.getStatus() != TrackedRaceStatusEnum.LOADING) {
if (newStatus.getStatus() != TrackedRaceStatusEnum.LOADING && newStatus.getStatus() != TrackedRaceStatusEnum.REMOVED) {
suspended = false;
}
} else if (newStatus.getStatus() == TrackedRaceStatusEnum.LOADING) {
@@ -3373,7 +3373,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
}
if (newStatus.getStatus() == TrackedRaceStatusEnum.LOADING && oldStatus != TrackedRaceStatusEnum.LOADING) {
suspendAllCachesNotUpdatingWhileLoading();
} else if (oldStatus == TrackedRaceStatusEnum.LOADING && newStatus.getStatus() != TrackedRaceStatusEnum.LOADING) {
} else if (oldStatus == TrackedRaceStatusEnum.LOADING && newStatus.getStatus() != TrackedRaceStatusEnum.LOADING && newStatus.getStatus() != TrackedRaceStatusEnum.REMOVED) {
resumeAllCachesNotUpdatingWhileLoading();
}
}
@@ -45,7 +45,7 @@ public class RaceTrackerMock extends AbstractRaceTrackerBaseImpl {
}
@Override
protected void onStop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException {
protected void onStop(boolean preemptive, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException {
isTracking = false;
}
@@ -144,7 +144,7 @@ public class RaceTrackerTest {
assertNotSame(oldTrackedRace, newTrackedRace);
assertNotSame(oldRaceDefinition, newTrackedRace.getRace());
} finally {
service.stopTracking(myRaceHandle.getRegatta());
service.stopTracking(myRaceHandle.getRegatta(), /* willBeRemoved */ false);
}
logger.exiting(getClass().getName(), "testStopTracking");
}
@@ -172,7 +172,7 @@ public class RaceTrackerTest {
assertSame(oldTrackedRace, newTrackedRace);
assertSame(raceHandle.getRaceTracker(), myRaceHandle.getRaceTracker());
} finally {
service.stopTracking(myRaceHandle.getRegatta());
service.stopTracking(myRaceHandle.getRegatta(), /* willBeRemoved */ false);
}
logger.exiting(getClass().getName(), "testStopTracking");
}
@@ -165,8 +165,9 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
* {@link #addTracTracRace(URL, URI, URI, WindStore, long)} with an equal combination of URLs/URIs, the {@link TracTracRaceTracker}
* already tracking the race was re-used. The trackers will be stopped by this call regardless of how many calls
* were made that ensured they were tracking.
* @param willBeRemoved TODO
*/
void stopTracking(Regatta regatta) throws MalformedURLException, IOException, InterruptedException;
void stopTracking(Regatta regatta, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException;
/**
* Removes <code>race</code> and any corresponding {@link #getTrackedRace(Regatta, RaceDefinition) tracked race}
@@ -196,7 +196,7 @@ public class Activator implements BundleActivator {
racingEventService.stopTrackingWind(windTracker.getA(), windTracker.getB());
}
for (Regatta regatta : racingEventService.getAllRegattas()) {
racingEventService.stopTracking(regatta);
racingEventService.stopTracking(regatta, /* willBeRemoved */ true);
}
for (ServiceRegistration<?> reg : registrations) {
reg.unregister();
@@ -745,7 +745,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
removeLeaderboard(leaderboardName);
}
for (Regatta regatta : new ArrayList<>(this.regattasByName.values())) {
stopTracking(regatta);
stopTracking(regatta, /* willBeRemoved */ true);
removeRegatta(regatta);
}
for (Event event : new ArrayList<>(this.eventsById.values())) {
@@ -1834,7 +1834,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
@Override
public void statusChanged(TrackedRaceStatus newStatus, TrackedRaceStatus oldStatus) {
if (oldStatus.getStatus() == TrackedRaceStatusEnum.LOADING
&& newStatus.getStatus() != TrackedRaceStatusEnum.LOADING) {
&& newStatus.getStatus() != TrackedRaceStatusEnum.LOADING && newStatus.getStatus() != TrackedRaceStatusEnum.REMOVED) {
if (polarDataService != null) {
polarDataService.raceFinishedLoading(race);
}
@@ -2084,7 +2084,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
@Override
public void stopTracking(Regatta regatta) throws MalformedURLException, IOException, InterruptedException {
public void stopTracking(Regatta regatta, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException {
final Set<RaceTracker> trackersForRegatta = raceTrackersByRegatta.get(regatta);
if (trackersForRegatta != null) {
for (RaceTracker raceTracker : trackersForRegatta) {
@@ -2092,7 +2092,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
if (race != null) {
stopTrackingWind(regatta, race);
}
raceTracker.stop(/* preemptive */false);
raceTracker.stop(/* preemptive */false, willBeRemoved);
final Object trackerId = raceTracker.getID();
final NamedReentrantReadWriteLock lock = lockRaceTrackersById(trackerId);
try {
@@ -2113,7 +2113,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
@Override
public void stopTrackingAndRemove(Regatta regatta) throws MalformedURLException, IOException, InterruptedException {
stopTracking(regatta);
stopTracking(regatta, /* willBeRemoved */ true);
if (regatta != null) {
if (regatta.getName() != null) {
logger.info("Removing regatta " + regatta.getName() + " (" + regatta.hashCode() + ") from " + this);
@@ -2163,7 +2163,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
if (trackersForRegatta != null) {
trackersForRegatta.remove(tracker);
}
tracker.stop(/* preemptive */true);
tracker.stop(/* preemptive */true, /* willBeRemoved */ true);
final Object trackerId = tracker.getID();
final NamedReentrantReadWriteLock lock = lockRaceTrackersById(trackerId);
try {
@@ -2172,7 +2172,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
unlockRaceTrackersById(trackerId, lock);
}
if (trackersForRegatta == null || trackersForRegatta.isEmpty()) {
stopTracking(regatta);
stopTracking(regatta, /* willBeRemoved */ true);
}
} catch (Exception e) {
logger.log(Level.SEVERE, "scheduleAbortTrackerAfterInitialTimeout", e);
@@ -2222,7 +2222,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
// if the last tracked race was removed, confirm that tracking for the entire regatta has stopped
if (trackerSet == null || trackerSet.isEmpty()) {
stopTracking(regatta);
stopTracking(regatta, /* willBeRemoved */ false);
}
}
@@ -2397,7 +2397,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
RaceTracker raceTracker = trackerIter.next();
if (raceTracker.getRace() == race) {
// firstly stop the tracker
raceTracker.stop(/* preemptive */true);
raceTracker.stop(/* preemptive */true, /* willBeRemoved */ true);
// remove it from the raceTrackers by Regatta
trackerIter.remove();
final Object trackerId = raceTracker.getID();
@@ -2409,7 +2409,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
// if the last tracked race was removed, remove the entire regatta
if (raceTrackersByRegatta.get(regatta).isEmpty()) {
stopTracking(regatta);
stopTracking(regatta, /* willBeRemoved */ true);
}
}
}