7534ece40a5223ffd2866ad97cd93d129aebeaa4
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/MarkPassingCalculator.java
| ... | ... | @@ -11,7 +11,6 @@ import java.util.Map; |
| 11 | 11 | import java.util.Map.Entry; |
| 12 | 12 | import java.util.Set; |
| 13 | 13 | import java.util.concurrent.Callable; |
| 14 | -import java.util.concurrent.CountDownLatch; |
|
| 15 | 14 | import java.util.concurrent.ExecutorService; |
| 16 | 15 | import java.util.concurrent.LinkedBlockingQueue; |
| 17 | 16 | import java.util.logging.Level; |
| ... | ... | @@ -64,8 +63,8 @@ public class MarkPassingCalculator { |
| 64 | 63 | private CandidateChooser chooser; |
| 65 | 64 | private static final Logger logger = Logger.getLogger(MarkPassingCalculator.class.getName()); |
| 66 | 65 | private final MarkPassingUpdateListener listener; |
| 67 | - private final static ExecutorService executor = ThreadPoolUtil.INSTANCE |
|
| 68 | - .getDefaultBackgroundTaskThreadPoolExecutor(); |
|
| 66 | + private final static ExecutorService executor = ThreadPoolUtil.INSTANCE.getDefaultBackgroundTaskThreadPoolExecutor(); |
|
| 67 | + private final static ExecutorService initializationExecutor = ThreadPoolUtil.INSTANCE.createBackgroundTaskThreadPoolExecutor("MarkPassingCalculator initializations"); |
|
| 69 | 68 | private final LinkedBlockingQueue<StorePositionUpdateStrategy> queue; |
| 70 | 69 | |
| 71 | 70 | /** |
| ... | ... | @@ -150,7 +149,7 @@ public class MarkPassingCalculator { |
| 150 | 149 | } else { |
| 151 | 150 | listen = null; |
| 152 | 151 | } |
| 153 | - Thread t = new Thread(() -> { |
|
| 152 | + final Runnable waitForInitialization = () -> { |
|
| 154 | 153 | final Set<Callable<Void>> tasks = new HashSet<>(); |
| 155 | 154 | for (Competitor c : race.getRace().getCompetitors()) { |
| 156 | 155 | tasks.add(race.getTrackedRegatta().cpuMeterCallable(() -> { |
| ... | ... | @@ -174,11 +173,11 @@ public class MarkPassingCalculator { |
| 174 | 173 | } |
| 175 | 174 | } |
| 176 | 175 | } |
| 177 | - }, "MarkPassingCalculator for race " + race.getRaceIdentifier() + " initialization"); |
|
| 176 | + }; |
|
| 178 | 177 | if (waitForInitialMarkPassingCalculation) { |
| 179 | - t.run(); |
|
| 178 | + waitForInitialization.run(); |
|
| 180 | 179 | } else { |
| 181 | - t.start(); |
|
| 180 | + initializationExecutor.submit(waitForInitialization); |
|
| 182 | 181 | } |
| 183 | 182 | } |
| 184 | 183 | |
| ... | ... | @@ -461,7 +460,6 @@ public class MarkPassingCalculator { |
| 461 | 460 | fixesForCompetitor.addAll(competitorEntry.getValue()); |
| 462 | 461 | } |
| 463 | 462 | if (!newMarkFixes.isEmpty()) { |
| 464 | - // FIXME bug 2745 use new mark fixes to invalidate chooser's mark position and mutual mark/waypoint distance cache |
|
| 465 | 463 | for (Entry<Competitor, List<GPSFixMoving>> fixesAffectedByNewMarkFixes : finder |
| 466 | 464 | .calculateFixesAffectedByNewMarkFixes(newMarkFixes).entrySet()) { |
| 467 | 465 | Collection<GPSFixMoving> fixes = combinedCompetitorFixesFinderConsidersAffected |
| ... | ... | @@ -592,7 +590,6 @@ public class MarkPassingCalculator { |
| 592 | 590 | suspended = false; |
| 593 | 591 | } else { |
| 594 | 592 | suspended = false; |
| 595 | - final CountDownLatch latchForRunningListenRun = new CountDownLatch(1); |
|
| 596 | 593 | enqueueUpdate(new StorePositionUpdateStrategy() { |
| 597 | 594 | @Override |
| 598 | 595 | public void storePositionUpdate(Map<Competitor, List<GPSFixMoving>> competitorFixes, |
| ... | ... | @@ -604,26 +601,17 @@ public class MarkPassingCalculator { |
| 604 | 601 | List<Pair<Competitor, Integer>> suppressedMarkPassings, |
| 605 | 602 | List<Competitor> unSuppressedMarkPassings, CandidateFinder candidateFinder, |
| 606 | 603 | CandidateChooser candidateChooser) { |
| 607 | - latchForRunningListenRun.countDown(); |
|
| 608 | - assert latchForRunningListenRun.getCount() == 0; |
|
| 604 | + if (markPassingRaceFingerprintRegistry != null) { |
|
| 605 | + initializationExecutor.submit(()->{ |
|
| 606 | + final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true); |
|
| 607 | + // TODO bug6182: do we need to store when we can assume that the race is still live? How to find out reliably? |
|
| 608 | + markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(), |
|
| 609 | + MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race), |
|
| 610 | + markPassings, race.getRace().getCourse()); |
|
| 611 | + }); |
|
| 612 | + } |
|
| 609 | 613 | } |
| 610 | 614 | }); |
| 611 | - if (markPassingRaceFingerprintRegistry != null) { |
|
| 612 | - new Thread(()->{ |
|
| 613 | - try { |
|
| 614 | - latchForRunningListenRun.await(); |
|
| 615 | - final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true); |
|
| 616 | - // TODO bug6182: do we need to store when we can assume that the race is still live? How to find out reliably? |
|
| 617 | - markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(), |
|
| 618 | - MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race), |
|
| 619 | - markPassings, race.getRace().getCourse()); |
|
| 620 | - } catch (InterruptedException e) { |
|
| 621 | - logger.log(Level.SEVERE, "Exception while waiting for Listen.run() to start processing in MarkPassingCalculator for "+ |
|
| 622 | - race.getName(), e); |
|
| 623 | - } |
|
| 624 | - }, "Waiting for mark passings for "+race.getName()+" after having resumed to store the results in registry") |
|
| 625 | - .start(); |
|
| 626 | - } |
|
| 627 | 615 | } |
| 628 | 616 | } |
| 629 | 617 | } finally { |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaDetailsCompositePO.java
| ... | ... | @@ -72,8 +72,8 @@ public class RegattaDetailsCompositePO extends PageArea { |
| 72 | 72 | if (entry != null) { |
| 73 | 73 | WebElement removeAction = ActionsHelper.findRemoveAction(entry.getWebElement()); |
| 74 | 74 | removeAction.click(); |
| 75 | - ActionsHelper.acceptAlert(this.driver); |
|
| 76 | - waitForAjaxRequests(); |
|
| 75 | + ActionsHelper.acceptAlert(this.driver); |
|
| 76 | + waitForAjaxRequests(); |
|
| 77 | 77 | } |
| 78 | 78 | } |
| 79 | 79 |
java/com.sap.sse.common/src/com/sap/sse/common/impl/RenamableImpl.java
| ... | ... | @@ -25,5 +25,4 @@ public class RenamableImpl implements Renamable { |
| 25 | 25 | public void setName(String newName) { |
| 26 | 26 | this.name = newName; |
| 27 | 27 | } |
| 28 | - |
|
| 29 | 28 | } |
java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceInitialLoadExtensionsDTO.java
| ... | ... | @@ -16,7 +16,7 @@ import com.sap.sse.security.shared.impl.LockingAndBanning; |
| 16 | 16 | * initial load format can be added to this DTO type. The benefit, compared to adding new content with |
| 17 | 17 | * explicit {@link ObjectOutputStream#writeObject(Object)} and {@link ObjectInputStream#readObject()} calls, |
| 18 | 18 | * is that there is a certain built-in backward compatibility when a replica with a new version and additional |
| 19 | - * fields expected in the initial load tries to replica from an older version where those fields don't exist |
|
| 19 | + * fields expected in the initial load tries to replicate from an older version where those fields don't exist |
|
| 20 | 20 | * yet in this type. Then, those additional fields will come out as {@code null} on the replica, and the replica |
| 21 | 21 | * at least has a chance to continue with a useful initialization of those data structures instead of having |
| 22 | 22 | * the replication of {@link SecurityService} and all subsequent {@link Replicable}s fail due to incompatible |