maintaining and using a RaceDefinition-->RaceTrackingConnectivityParameters map in RacingEventServiceImpl to remove races from restore list upon removeRace

Change-Id: I31d7d7da1ad50c6625321f175b9f04b27a1a4525
This commit is contained in:
Axel Uhl
2016-12-29 20:17:38 +01:00
parent 9aed690264
commit 6cfec72b83
2 changed files with 32 additions and 5 deletions
@@ -79,6 +79,7 @@ public interface RaceTracker {
/**
* Listener interface for race tracker related events
*/
@FunctionalInterface
interface Listener {
/**
* Tracker has stopped event, see {@link RaceTracker#stop(boolean)} method
@@ -88,6 +89,7 @@ public interface RaceTracker {
void onTrackerWillStop(boolean preemptive);
}
@FunctionalInterface
interface RaceCreationListener {
/**
* Tracker has received its {@link RaceDefinition}, so that now {@link RaceTracker#getRace} no longer returns
@@ -98,7 +98,6 @@ import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
@@ -440,7 +439,9 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
private final TrackedRegattaListener trackedRegattaListener;
private transient ConcurrentHashMap<Leaderboard, ScoreCorrectionListener> scoreCorrectionListenersByLeaderboard;
private transient final ConcurrentHashMap<Leaderboard, ScoreCorrectionListener> scoreCorrectionListenersByLeaderboard;
private transient final ConcurrentHashMap<RaceDefinition, RaceTrackingConnectivityParameters> connectivityParametersByRace;
/**
* Providing the constructor parameters for a new {@link RacingEventServiceImpl} instance is a bit tricky
@@ -569,6 +570,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
TrackedRegattaListener trackedRegattaListener, SailingNotificationService sailingNotificationService, boolean restoreTrackedRaces) {
logger.info("Created " + this);
this.scoreCorrectionListenersByLeaderboard = new ConcurrentHashMap<>();
this.connectivityParametersByRace = new ConcurrentHashMap<>();
this.notificationService = sailingNotificationService;
final ConstructorParameters constructorParameters = constructorParametersProvider.apply(this);
this.domainObjectFactory = constructorParameters.getDomainObjectFactory();
@@ -1463,6 +1465,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
// TODO bug 2: we need to link the params to the TrackedRace / RaceDefinition such that when the RaceDefinition is removed using removeRace(Regatta, RaceDefinition) then we know which params to remove from the restore store again
getMongoObjectFactory().addConnectivityParametersForRaceToRestore(params);
tracker.add((RaceTracker t) -> rememberConnectivityParametersForRace(t));
} else {
logger.warning("Race tracker with ID "+trackerID+" already found; not tracking twice to avoid race duplication");
WindStore existingTrackersWindStore = tracker.getWindStore();
@@ -1480,6 +1483,26 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
}
/**
* Remembers the link between the {@link RaceDefinition} that the {@code tracker} just produced and its
* {@link RaceTracker#getConnectivityParams() connectivity parameters}. This is important for later removing those
* connectivity parameters from the
* {@link MongoObjectFactory#removeConnectivityParametersForRaceToRestore(RaceTrackingConnectivityParameters) DB}
* when the {@link #removeRace(Regatta, RaceDefinition) race is removed}.
*
* @param tracker
* must have produced a {@link RaceDefinition} which can be guaranteed by waiting for the callback on a
* {@link RaceTracker.RaceCreationListener}
* {@link RaceTracker#add(com.sap.sailing.domain.tracking.RaceTracker.RaceCreationListener) registered}
* on that tracker and not calling this method before that listener has fired.
*/
private void rememberConnectivityParametersForRace(RaceTracker tracker) {
final RaceDefinition race = tracker.getRace(); // guaranteed to be != null by callback
assert race != null;
final RaceTrackingConnectivityParameters connectivityParams = tracker.getConnectivityParams();
connectivityParametersByRace.put(race, connectivityParams);
}
/**
* The regatta and all its contained {@link Regatta#getAllRaces() races} are replicated to all replicas.
*
@@ -2222,9 +2245,10 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
public void removeRace(Regatta regatta, RaceDefinition race) throws MalformedURLException, IOException,
InterruptedException {
logger.info("Removing the race " + race + "...");
// TODO bug 2, comment #7: this won't work... we need the mapping from TrackedRace or RaceDefinition to RaceTrackingConnectivityParameters
getRaceTrackerByRegattaAndRaceIdentifier(new RegattaNameAndRaceName(regatta.getName(), race.getName()),
tracker->getMongoObjectFactory().removeConnectivityParametersForRaceToRestore(tracker.getConnectivityParams()));
final RaceTrackingConnectivityParameters connectivityParams = connectivityParametersByRace.remove(race);
if (connectivityParams != null) {
getMongoObjectFactory().removeConnectivityParametersForRaceToRestore(connectivityParams);
}
stopAllTrackersForWhichRaceIsLastReachable(regatta, race);
stopTrackingWind(regatta, race);
TrackedRace trackedRace = getExistingTrackedRace(regatta, race);
@@ -2880,6 +2904,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
} finally {
LockUtil.unlockAfterWrite(leaderboardsByNameLock);
}
connectivityParametersByRace.clear();
eventsById.clear();
mediaLibrary.clear();
competitorStore.clear();