Fixed a NPE when starting Smartphone-Tracking

This commit is contained in:
Steffen Schaefer committed 2016-07-07 13:43:37 +02:00
1 parent b20ab0c1cb
commit c3a2443930
3 files changed
+68 -21

No files matched your search

@@ -12,6 +12,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
@@ -618,5 +619,5 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
Iterable<Competitor> getCompetitorInOrderOfWindwardDistanceTraveledFarthestFirst(TrackedRace trackedRace, TimePoint timePoint);
RaceTracker getRaceTrackerByRegattaAndRaceIdentifier(RegattaAndRaceIdentifier raceIdentifier);
void getRaceTrackerByRegattaAndRaceIdentifier(RegattaAndRaceIdentifier raceIdentifier, Consumer<RaceTracker> callback);
}
@@ -35,6 +35,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -302,6 +303,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
*/
private final ConcurrentHashMap<Object, NamedReentrantReadWriteLock> raceTrackersByIDLocks;
private transient ConcurrentHashMap<RegattaAndRaceIdentifier, Set<Consumer<RaceTracker>>> raceTrackerCallbacks;
/**
* Leaderboards managed by this racing event service
*/
@@ -578,6 +581,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
false);
raceTrackersByID = new ConcurrentHashMap<>();
raceTrackersByIDLocks = new ConcurrentHashMap<>();
raceTrackerCallbacks = new ConcurrentHashMap<>();
leaderboardGroupsByName = new ConcurrentHashMap<>();
leaderboardGroupsByID = new ConcurrentHashMap<>();
leaderboardGroupsByNameLock = new NamedReentrantReadWriteLock("leaderboardGroupsByName for " + this, /* fair */
@@ -1379,6 +1383,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
raceTrackersByRegatta.put(tracker.getRegatta(), trackers);
}
trackers.add(tracker);
notifyListenersForNewRaceTracker(tracker);
} finally {
LockUtil.unlockAfterWrite(raceTrackersByRegattaLock);
}
@@ -3342,17 +3347,53 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
return result;
}
@Override
public RaceTracker getRaceTrackerByRegattaAndRaceIdentifier(RegattaAndRaceIdentifier raceIdentifier) {
public void getRaceTrackerByRegattaAndRaceIdentifier(RegattaAndRaceIdentifier raceIdentifier,
Consumer<RaceTracker> callback) {
LockUtil.lockForRead(regattasByNameLock);
Regatta regatta = regattasByName.get(raceIdentifier.getRegattaName());
LockUtil.unlockAfterRead(regattasByNameLock);
if (regatta != null) {
for (RaceTracker raceTracker : raceTrackersByRegatta.get(regatta)) {
if (raceTracker.getRaceIdentifiers().contains(raceIdentifier)) {
return raceTracker;
LockUtil.lockForRead(raceTrackersByRegattaLock);
try {
Set<RaceTracker> raceTrackersForRegatta = raceTrackersByRegatta.get(regatta);
for (RaceTracker raceTracker : raceTrackersForRegatta) {
if (raceTracker.getRaceIdentifiers().contains(raceIdentifier)) {
callback.accept(raceTracker);
return;
}
}
Util.addToValueSet(getRaceTrackerCallbacks(), raceIdentifier, callback);
} finally {
LockUtil.unlockAfterRead(raceTrackersByRegattaLock);
}
}
}
private ConcurrentHashMap<RegattaAndRaceIdentifier, Set<Consumer<RaceTracker>>> getRaceTrackerCallbacks() {
if (raceTrackerCallbacks == null) {
synchronized (this) {
if (raceTrackerCallbacks == null) {
raceTrackerCallbacks = new ConcurrentHashMap<>();
}
}
}
return null;
return raceTrackerCallbacks;
}
private void notifyListenersForNewRaceTracker(RaceTracker tracker) {
LockUtil.lockForRead(raceTrackersByRegattaLock);
try {
tracker.getRaceIdentifiers().forEach((raceIdentifier) -> {
Set<Consumer<RaceTracker>> callbacks = getRaceTrackerCallbacks().remove(raceIdentifier);
if (callbacks != null) {
callbacks.forEach((callback) -> callback.accept(tracker));
}
});
} finally {
LockUtil.unlockAfterRead(raceTrackersByRegattaLock);
}
}
}