From 4b8afb0e0cbbc6851057fb663c39993dfb6e75dd Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 27 Aug 2024 15:03:10 +0200 Subject: [PATCH 1/5] improved data mining ProcessorQuery; when trying to abort a query that has already terminated, the temrination status is preserved instead of overwriting it with the ABORTED state --- .../src/com/sap/sse/datamining/impl/ProcessorQuery.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java index 38b098193c2..10fdb2a24c4 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java @@ -224,7 +224,7 @@ public abstract class ProcessorQuery implements Quer public void abort() { synchronized (monitorObject) { LOGGER.log(Level.INFO, "Aborting the query processing"); - state = QueryState.ABORTED; + state = state == QueryState.RUNNING || state == QueryState.NOT_STARTED ? QueryState.ABORTED : state; monitorObject.notify(); } } From f7dcceb758640cf92de2acd9600d2c0dd158aade Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 27 Aug 2024 15:31:12 +0200 Subject: [PATCH 2/5] use same MongoDB client session for fix store and metadata collection --- .../racelog/tracking/impl/MetadataCollection.java | 3 +-- .../racelogtracking/test/impl/SensorFixStoreTest.java | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MetadataCollection.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MetadataCollection.java index 1d6c5c1fb3b..04caf73f2c9 100755 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MetadataCollection.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MetadataCollection.java @@ -113,8 +113,7 @@ public class MetadataCollection extends MongoFixHandler { return result; } - long getNumberOfFixes(DeviceIdentifier device) - throws TransformationException, NoCorrespondingServiceRegisteredException { + long getNumberOfFixes(DeviceIdentifier device) throws TransformationException, NoCorrespondingServiceRegisteredException { final Document resultDocument = findMetadataObject(device); final long result; if (resultDocument == null) { diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreTest.java b/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreTest.java index 92fa3c107fa..8195644bec9 100644 --- a/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreTest.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreTest.java @@ -46,12 +46,10 @@ public class SensorFixStoreTest { protected final DeviceIdentifier device2 = new SmartphoneImeiIdentifier("b"); protected SensorFixStore store; private ClientSession clientSession; - private ClientSession metadataCollectionClientSession; @Before public void setUp() throws UnknownHostException, MongoException { clientSession = MongoDBService.INSTANCE.startCausallyConsistentSession(); - metadataCollectionClientSession = MongoDBService.INSTANCE.startCausallyConsistentSession(); dropPersistedData(); newStore(); } @@ -59,7 +57,7 @@ public class SensorFixStoreTest { private void newStore() { store = new MongoSensorFixStoreImpl(PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, ReadConcern.MAJORITY, - WriteConcern.MAJORITY, clientSession, metadataCollectionClientSession); + WriteConcern.MAJORITY, clientSession, clientSession); } @After @@ -70,7 +68,7 @@ public class SensorFixStoreTest { private void dropPersistedData() { MongoDatabase db = PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory().getDatabase(); db.getCollection(CollectionNames.GPS_FIXES.name()).withWriteConcern(WriteConcern.MAJORITY).drop(clientSession); - db.getCollection(CollectionNames.GPS_FIXES_METADATA.name()).withWriteConcern(WriteConcern.MAJORITY).drop(metadataCollectionClientSession); + db.getCollection(CollectionNames.GPS_FIXES_METADATA.name()).withWriteConcern(WriteConcern.MAJORITY).drop(clientSession); } @Test From f319b2548205fef7bd09a335aebf15a7cf5741a7 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 27 Aug 2024 19:05:49 +0200 Subject: [PATCH 3/5] bug6051: implement leg type of first leg as dimension on Race --- .../Sailing_StringMessages.properties | 3 +- .../Sailing_StringMessages_de.properties | 3 +- .../data/HasTrackedRaceContext.java | 5 +++ .../impl/data/TrackedRaceWithContext.java | 31 +++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index fcf1931cdf4..2741475ccfc 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -273,4 +273,5 @@ SmoothedSpeed=Smoothed Speed RatioDistanceLongVsShortTack=Ratio distance long tack / short tack RatioDurationLongVsShortTack=Ratio duration long tack / short tack Discarded=Discarded -DurationFromRaceStartToFirstTack=Duration from race start to first tack \ No newline at end of file +DurationFromRaceStartToFirstTack=Duration from race start to first tack +TypeOfFirstLeg=Type of first leg \ No newline at end of file diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index f7e381a7515..79aa61c04df 100755 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -271,4 +271,5 @@ SmoothedSpeed=Geglättete Geschwindigkeit RatioDistanceLongVsShortTack=Verhältnis gesegelte Distanz auf Streck- zu Holebug RatioDurationLongVsShortTack=Verhältnis gesegelte Dauer auf Streck- zu Holebug Discarded=Gestrichen -DurationFromRaceStartToFirstTack=Dauer vom Start der Wettfahrt bis zur ersten Wende \ No newline at end of file +DurationFromRaceStartToFirstTack=Dauer vom Start der Wettfahrt bis zur ersten Wende +TypeOfFirstLeg=Art des ersten Bahnschenkels \ No newline at end of file diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedRaceContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedRaceContext.java index 4b407dd1bbb..6fb0868a46f 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedRaceContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedRaceContext.java @@ -6,7 +6,9 @@ import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; +import com.sap.sailing.domain.common.LegType; import com.sap.sailing.domain.common.NauticalSide; +import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.Bearing; import com.sap.sse.common.Distance; @@ -87,6 +89,9 @@ public interface HasTrackedRaceContext { @Dimension(messageKey="Day") public String getDayAsISO(); + + @Dimension(messageKey="TypeOfFirstLeg") + public LegType getTypeOfFirstLeg() throws NoWindException; // Convenience methods for race dependent calculation to avoid code duplication public Double getRelativeScoreForCompetitor(Competitor competitor); diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedRaceWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedRaceWithContext.java index ca8e35039ca..91fc212e665 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedRaceWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedRaceWithContext.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.List; import java.util.TimeZone; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; @@ -19,18 +20,23 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.Course; import com.sap.sailing.domain.base.CourseArea; import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.Fleet; +import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; +import com.sap.sailing.domain.common.LegType; import com.sap.sailing.domain.common.NauticalSide; +import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.tracking.LineDetails; import com.sap.sailing.domain.tracking.Track; +import com.sap.sailing.domain.tracking.TrackedLeg; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.geocoding.ReverseGeocoder; import com.sap.sse.common.Bearing; @@ -473,4 +479,29 @@ public class TrackedRaceWithContext implements HasTrackedRaceContext { } return cachedDayAsISO; } + + @Override + public LegType getTypeOfFirstLeg() throws NoWindException { + final LegType result; + final TimePoint startOfRace = getTrackedRace().getStartOfRace(); + if (startOfRace == null) { + result = null; + } else { + final Course course = getTrackedRace().getRace().getCourse(); + final List legs = course.getLegs(); + if (legs.isEmpty()) { + result = null; + } else { + final TrackedLeg firstTrackedLeg = getTrackedRace().getTrackedLeg(legs.get(0)); + if (firstTrackedLeg == null) { + result = null; + } else { + result = firstTrackedLeg.getLegType(startOfRace); + } + } + } + return result; + } + + } \ No newline at end of file From 1fd822fad1be7a9ce76dca31f24bcf3a996d48a9 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 27 Aug 2024 19:06:40 +0200 Subject: [PATCH 4/5] removed unnecessary and unstable test verdict --- .../sse/datamining/impl/TestAbortingHeavyLoadQuery.java | 9 ++++----- .../util/components/StatefulBlockingInstruction.java | 3 +-- .../util/components/StatefulProcessorInstruction.java | 1 - 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestAbortingHeavyLoadQuery.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestAbortingHeavyLoadQuery.java index e7a37929630..a2ece725144 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestAbortingHeavyLoadQuery.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestAbortingHeavyLoadQuery.java @@ -130,10 +130,9 @@ public class TestAbortingHeavyLoadQuery { query.abort(); QueryResult> result = queryTask.get(); - // The query execution returned, so all processors are aborted (checked below). + // The query execution returned, so all processors have received the abort signal (checked below). // The number of unfinished instructions mustn't change after this point int unfinishedInstructionsCount = unfinishedInstructions.size(); - boolean unfinishedInstructionWasFinished = false; Set> runningInstructions = new HashSet<>(); Set> notStartedInstructions = new HashSet<>(); for (StatefulProcessorInstruction instruction : unfinishedInstructions) { @@ -142,13 +141,11 @@ public class TestAbortingHeavyLoadQuery { } else { notStartedInstructions.add(instruction); } - unfinishedInstructionWasFinished |= instruction.computeResultWasFinished(); } logExecution(unfinishedInstructionsCount + " unfinished instructions left - " + runningInstructions.size() + " running, " + notStartedInstructions.size() + " not started"); printExecutionRecord(); assertThat("Number of unfinished instructions changed", runningInstructions.size() + notStartedInstructions.size(), is(unfinishedInstructionsCount)); - assertFalse("Unfinished instructions expected, but at least one was completed", unfinishedInstructionWasFinished); // Checking query, result and processor chain state assertThat(query.getState(), is(QueryState.ABORTED)); @@ -365,7 +362,9 @@ public class TestAbortingHeavyLoadQuery { @Override public void afterInstructionFinished(ProcessorInstruction instruction) { super.afterInstructionFinished(instruction); - if(canProcessElements()) unfinishedInstructions.remove(instruction); + if (canProcessElements()) { + unfinishedInstructions.remove(instruction); + } } }; Processor, String> retriever0 = new AbstractRetrievalProcessor, String>(dataSourceType, String.class, executor, Collections.singleton(retriever1), 0, "") { diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulBlockingInstruction.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulBlockingInstruction.java index e9a9b952ae3..6a51df7559a 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulBlockingInstruction.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulBlockingInstruction.java @@ -46,7 +46,7 @@ public class StatefulBlockingInstruction extends StatefulProcessorIn } return result; } - + protected void actionBeforeBlock() { } protected void actionBeforeAbort() { } protected void actionAfterBlock() { } @@ -58,5 +58,4 @@ public class StatefulBlockingInstruction extends StatefulProcessorIn public boolean computeResultWasAborted() { return computeResultWasAborted; } - } \ No newline at end of file diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulProcessorInstruction.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulProcessorInstruction.java index 0e299a2b0ec..50f544cd526 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulProcessorInstruction.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulProcessorInstruction.java @@ -50,5 +50,4 @@ public abstract class StatefulProcessorInstruction extends AbstractP public boolean computeResultWasFinished() { return computeResultWasFinished; } - } From ddf407c8b2475180a9f8b589ff2ece051c168ce4 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 28 Aug 2024 09:34:06 +0200 Subject: [PATCH 5/5] bug6051: release notes for new first leg type dimension --- .../places/whatsnew/resources/SailingAnalyticsNotes.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html index adf355c1201..20cb7351501 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html @@ -13,6 +13,8 @@ lines or course middle lines) from showing when hovering the mouse over them.
  • In Data Mining, race results now have a new dimension "Discarded" for grouping and filtering.
  • Races of competitors now have a new statistic in Data Mining: duration since start to first tack.
  • +
  • New data mining dimension for races: type of first leg. This way, races can be filtered or results can + be grouped by whether a race's first leg is an upwind, reaching or downwind leg.
  • July 2024