mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-27 16:06:39 +00:00
added synchronization to fix bug 1046 (ConcurrentModificationException while loading score corrections and at the same time attaching a tracked race)
This commit is contained in:
+76
-47
@@ -67,29 +67,35 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
|
||||
@Override
|
||||
public void setCarriedPoints(String competitorName, double carriedPoints) {
|
||||
assertNoTrackedRaceAssociatedYet();
|
||||
carriedPointsByCompetitorName.put(competitorName, carriedPoints);
|
||||
synchronized (carriedPointsByCompetitorName) {
|
||||
carriedPointsByCompetitorName.put(competitorName, carriedPoints);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxPointsReason(String competitorName, RaceColumn raceColumn, MaxPointsReason maxPointsReason) {
|
||||
assertNoTrackedRaceAssociatedYet();
|
||||
Map<RaceColumn, MaxPointsReason> map = maxPointsReasonsByCompetitorName.get(competitorName);
|
||||
if (map == null) {
|
||||
map = new HashMap<RaceColumn, MaxPointsReason>();
|
||||
maxPointsReasonsByCompetitorName.put(competitorName, map);
|
||||
synchronized (maxPointsReasonsByCompetitorName) {
|
||||
Map<RaceColumn, MaxPointsReason> map = maxPointsReasonsByCompetitorName.get(competitorName);
|
||||
if (map == null) {
|
||||
map = new HashMap<RaceColumn, MaxPointsReason>();
|
||||
maxPointsReasonsByCompetitorName.put(competitorName, map);
|
||||
}
|
||||
map.put(raceColumn, maxPointsReason);
|
||||
}
|
||||
map.put(raceColumn, maxPointsReason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void correctScore(String competitorName, RaceColumn raceColumn, double correctedScore) {
|
||||
assertNoTrackedRaceAssociatedYet();
|
||||
Map<RaceColumn, Double> map = correctedScoresByCompetitorName.get(competitorName);
|
||||
if (map == null) {
|
||||
map = new HashMap<RaceColumn, Double>();
|
||||
correctedScoresByCompetitorName.put(competitorName, map);
|
||||
synchronized (correctedScoresByCompetitorName) {
|
||||
Map<RaceColumn, Double> map = correctedScoresByCompetitorName.get(competitorName);
|
||||
if (map == null) {
|
||||
map = new HashMap<RaceColumn, Double>();
|
||||
correctedScoresByCompetitorName.put(competitorName, map);
|
||||
}
|
||||
map.put(raceColumn, correctedScore);
|
||||
}
|
||||
map.put(raceColumn, correctedScore);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,48 +111,67 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
|
||||
for (Competitor competitor : race.getRace().getCompetitors()) {
|
||||
competitorsByName.put(competitor.getName(), competitor);
|
||||
}
|
||||
for (Iterator<Map.Entry<String, Double>> carryEntryIter = carriedPointsByCompetitorName.entrySet().iterator(); carryEntryIter.hasNext(); ) {
|
||||
Map.Entry<String, Double> carryEntry = carryEntryIter.next();
|
||||
if (competitorsByName.containsKey(carryEntry.getKey())) {
|
||||
leaderboard.setCarriedPoints(competitorsByName.get(carryEntry.getKey()), carryEntry.getValue());
|
||||
carryEntryIter.remove();
|
||||
}
|
||||
}
|
||||
for (Iterator<java.util.Map.Entry<String, Map<RaceColumn, MaxPointsReason>>> maxPointsReasonsEntryIter =
|
||||
maxPointsReasonsByCompetitorName.entrySet().iterator(); maxPointsReasonsEntryIter.hasNext();) {
|
||||
java.util.Map.Entry<String, Map<RaceColumn, MaxPointsReason>> maxPointsReasonEntries = maxPointsReasonsEntryIter.next();
|
||||
if (competitorsByName.containsKey(maxPointsReasonEntries.getKey())) {
|
||||
for (Map.Entry<RaceColumn, MaxPointsReason> maxPointsReasonEntry : maxPointsReasonEntries.getValue().entrySet()) {
|
||||
leaderboard.getScoreCorrection().setMaxPointsReason(competitorsByName.get(maxPointsReasonEntries.getKey()),
|
||||
maxPointsReasonEntry.getKey(), maxPointsReasonEntry.getValue());
|
||||
synchronized (carriedPointsByCompetitorName) {
|
||||
for (Iterator<Map.Entry<String, Double>> carryEntryIter = carriedPointsByCompetitorName.entrySet()
|
||||
.iterator(); carryEntryIter.hasNext();) {
|
||||
Map.Entry<String, Double> carryEntry = carryEntryIter.next();
|
||||
if (competitorsByName.containsKey(carryEntry.getKey())) {
|
||||
leaderboard.setCarriedPoints(competitorsByName.get(carryEntry.getKey()), carryEntry.getValue());
|
||||
carryEntryIter.remove();
|
||||
}
|
||||
maxPointsReasonsEntryIter.remove();
|
||||
}
|
||||
}
|
||||
for (Iterator<java.util.Map.Entry<String, Map<RaceColumn, Double>>> correctedScoresEntryIter =
|
||||
correctedScoresByCompetitorName.entrySet().iterator(); correctedScoresEntryIter.hasNext();) {
|
||||
java.util.Map.Entry<String, Map<RaceColumn, Double>> correctedScoresEntries = correctedScoresEntryIter.next();
|
||||
if (competitorsByName.containsKey(correctedScoresEntries.getKey())) {
|
||||
for (java.util.Map.Entry<RaceColumn, Double> correctedScoreEntry : correctedScoresEntries.getValue().entrySet()) {
|
||||
leaderboard.getScoreCorrection().correctScore(competitorsByName.get(correctedScoresEntries.getKey()),
|
||||
correctedScoreEntry.getKey(), correctedScoreEntry.getValue());
|
||||
synchronized (maxPointsReasonsByCompetitorName) {
|
||||
for (Iterator<java.util.Map.Entry<String, Map<RaceColumn, MaxPointsReason>>> maxPointsReasonsEntryIter = maxPointsReasonsByCompetitorName
|
||||
.entrySet().iterator(); maxPointsReasonsEntryIter.hasNext();) {
|
||||
java.util.Map.Entry<String, Map<RaceColumn, MaxPointsReason>> maxPointsReasonEntries = maxPointsReasonsEntryIter
|
||||
.next();
|
||||
if (competitorsByName.containsKey(maxPointsReasonEntries.getKey())) {
|
||||
for (Map.Entry<RaceColumn, MaxPointsReason> maxPointsReasonEntry : maxPointsReasonEntries
|
||||
.getValue().entrySet()) {
|
||||
leaderboard.getScoreCorrection().setMaxPointsReason(
|
||||
competitorsByName.get(maxPointsReasonEntries.getKey()), maxPointsReasonEntry.getKey(),
|
||||
maxPointsReasonEntry.getValue());
|
||||
}
|
||||
maxPointsReasonsEntryIter.remove();
|
||||
}
|
||||
correctedScoresEntryIter.remove();
|
||||
}
|
||||
}
|
||||
for (Iterator<java.util.Map.Entry<String, String>> displayNamesEntryIter =
|
||||
displayNamesByCompetitorName.entrySet().iterator(); displayNamesEntryIter.hasNext();) {
|
||||
java.util.Map.Entry<String, String> displayNamesEntry = displayNamesEntryIter.next();
|
||||
if (competitorsByName.containsKey(displayNamesEntry.getKey())) {
|
||||
leaderboard.setDisplayName(competitorsByName.get(displayNamesEntry.getKey()), displayNamesEntry.getValue());
|
||||
displayNamesEntryIter.remove();
|
||||
synchronized (correctedScoresByCompetitorName) {
|
||||
for (Iterator<java.util.Map.Entry<String, Map<RaceColumn, Double>>> correctedScoresEntryIter = correctedScoresByCompetitorName
|
||||
.entrySet().iterator(); correctedScoresEntryIter.hasNext();) {
|
||||
java.util.Map.Entry<String, Map<RaceColumn, Double>> correctedScoresEntries = correctedScoresEntryIter
|
||||
.next();
|
||||
if (competitorsByName.containsKey(correctedScoresEntries.getKey())) {
|
||||
for (java.util.Map.Entry<RaceColumn, Double> correctedScoreEntry : correctedScoresEntries
|
||||
.getValue().entrySet()) {
|
||||
leaderboard.getScoreCorrection().correctScore(
|
||||
competitorsByName.get(correctedScoresEntries.getKey()), correctedScoreEntry.getKey(),
|
||||
correctedScoreEntry.getValue());
|
||||
}
|
||||
correctedScoresEntryIter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator<String> suppressedCompetitorNameIter=suppressedCompetitorNames.iterator(); suppressedCompetitorNameIter.hasNext(); ) {
|
||||
String next = suppressedCompetitorNameIter.next();
|
||||
if (competitorsByName.containsKey(next)) {
|
||||
leaderboard.setSuppressed(competitorsByName.get(next), true);
|
||||
suppressedCompetitorNameIter.remove();
|
||||
synchronized (displayNamesByCompetitorName) {
|
||||
for (Iterator<java.util.Map.Entry<String, String>> displayNamesEntryIter = displayNamesByCompetitorName
|
||||
.entrySet().iterator(); displayNamesEntryIter.hasNext();) {
|
||||
java.util.Map.Entry<String, String> displayNamesEntry = displayNamesEntryIter.next();
|
||||
if (competitorsByName.containsKey(displayNamesEntry.getKey())) {
|
||||
leaderboard.setDisplayName(competitorsByName.get(displayNamesEntry.getKey()),
|
||||
displayNamesEntry.getValue());
|
||||
displayNamesEntryIter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized (suppressedCompetitorNames) {
|
||||
for (Iterator<String> suppressedCompetitorNameIter = suppressedCompetitorNames.iterator(); suppressedCompetitorNameIter
|
||||
.hasNext();) {
|
||||
String next = suppressedCompetitorNameIter.next();
|
||||
if (competitorsByName.containsKey(next)) {
|
||||
leaderboard.setSuppressed(competitorsByName.get(next), true);
|
||||
suppressedCompetitorNameIter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAsListenerIfNoLeftOvers();
|
||||
@@ -163,13 +188,17 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
|
||||
@Override
|
||||
public void setDisplayName(String competitorName, String displayName) {
|
||||
assertNoTrackedRaceAssociatedYet();
|
||||
displayNamesByCompetitorName.put(competitorName, displayName);
|
||||
synchronized (displayNamesByCompetitorName) {
|
||||
displayNamesByCompetitorName.put(competitorName, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suppressCompetitor(String competitorName) {
|
||||
assertNoTrackedRaceAssociatedYet();
|
||||
suppressedCompetitorNames.add(competitorName);
|
||||
synchronized (suppressedCompetitorNames) {
|
||||
suppressedCompetitorNames.add(competitorName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,4 +9,5 @@
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.sap.sailing.domain.swisstimingadapter.persistence.StoreAndForward"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="3500 3501"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.domain.swisstimingadapter.persistence"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties"/>
|
||||
</launchConfiguration>
|
||||
|
||||
+18
-2
@@ -280,11 +280,27 @@ public class StoreAndForward implements Runnable {
|
||||
SailMasterMessage message = swissTimingFactory.createMessage(messageAndOptionalSequenceNumber.getA(), lastMessageCount);
|
||||
swissTimingAdapterPersistence.storeSailMasterMessage(message);
|
||||
synchronized (this) {
|
||||
for (OutputStream os : streamsToForwardTo) {
|
||||
for (OutputStream os : new ArrayList<OutputStream>(streamsToForwardTo)) {
|
||||
// write the sequence number of the message into the stream before actually writing the
|
||||
// SwissTiming message
|
||||
try {
|
||||
// TODO if forwarding to os doesn't work, e.g., because the socket was closed or the client died, remove os from streamsToForwardTo and the socket from socketsToForwardTo
|
||||
transceiver.sendMessage(message, os);
|
||||
transceiver.sendMessage(message, os);
|
||||
} catch (Throwable e) {
|
||||
int i=streamsToForwardTo.indexOf(os);
|
||||
try {
|
||||
os.close();
|
||||
} catch (Throwable t) {
|
||||
logger.throwing(StoreAndForward.class.getName(), "run", t);
|
||||
}
|
||||
streamsToForwardTo.remove(os);
|
||||
Socket s = socketsToForwardTo.remove(i);
|
||||
try {
|
||||
s.close();
|
||||
} catch (Throwable t) {
|
||||
logger.throwing(StoreAndForward.class.getName(), "run", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!stopped) {
|
||||
|
||||
Reference in New Issue
Block a user