From ec097a63e764a1826df697cec54c2dd0e438e564 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 26 Jun 2015 21:56:55 +0200 Subject: [PATCH] started to work on bug 3022, cleaning up the DistanceCache leaking mess --- .../sap/sailing/domain/test/TrackTest.java | 43 +++++++++++++++++++ .../domain/tracking/impl/GPSFixTrackImpl.java | 4 +- .../src/com/sap/sse/common/Duration.java | 1 + .../common/impl/MillisecondsDurationImpl.java | 5 +++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java index 5e2870f4516..f2795b3b304 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java @@ -53,6 +53,7 @@ import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl; import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl; import com.sap.sailing.domain.tracking.impl.MaxSpeedCache; import com.sap.sailing.domain.tracking.impl.TrackImpl; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimeRange; import com.sap.sse.common.Timed; @@ -894,6 +895,48 @@ public class TrackTest { assertEquals(toReachInOneThirdOfTimeBetweenFixesInMillis.getMeters(), distance3_new.getMeters()-distance2_new.getMeters(), 0.01); assertEquals(toReachInOneThirdOfTimeBetweenFixesInMillis.getMeters(), distance4_new.getMeters()-distance3_new.getMeters(), 0.01); } + + /** + * Bug 3022 describes a {@link StackOverflowError} that occurs during distance calculations on a {@link GPSFixTrackImpl}. + * This test tries to reproduce this behavior, as a starting point for a fix. The recursion happened while a long-distance + * race was running. Can there be a certain fix insertion pattern that, combined with a certain request pattern, + * produces degenerated cache contents? The race had a live delay of 660s. The trackers were configured to sample every + * 120s and to send every 600s. This could mean that for some 60s the live requests were "ahead" of the trackers. + */ + @Test + public void testDistanceCacheIncrementalFillUpAndRecursion() { + TimePoint start = MillisecondsTimePoint.now(); + TimePoint fixTime = start; + TimePoint queryTime = fixTime; + Position p = new DegreePosition(0, 0); + Bearing cog = new DegreeBearingImpl(123); + final Duration queryInterval = Duration.ONE_SECOND; + final Duration readAhead = Duration.ONE_MINUTE; + final Duration samplingInterval = Duration.ONE_SECOND.times(120); + final Duration transmissionInterval = Duration.ONE_MINUTE.times(10); + final Duration raceDuration = Duration.ONE_HOUR.times(48); + final Speed speed = new KnotSpeedImpl(12); + final Distance distancePerSample = speed.travel(fixTime, fixTime.plus(samplingInterval)); + DynamicGPSFixTrack track = new DynamicGPSFixTrackImpl(new Object(), /* millisecondsOverWhichToAverage */ 30000l); + while (fixTime.before(start.plus(raceDuration))) { + for (int i=0; i= 0); + lastDistance = d; + queryTime = queryTime.plus(queryInterval); + } + } + System.out.println(); + } @Test public void testDistanceCacheAccessForPartialStrip() { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java index 8cf2cc16b9f..cd7ee6a0467 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java @@ -554,7 +554,9 @@ public class GPSFixTrackImpl extends TrackImpl } finally { unlockAfterRead(); } - getDistanceCache().cache(from, to, result); + if (recursionDepth == 0) { + getDistanceCache().cache(from, to, result); + } } return result; } diff --git a/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java b/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java index a874fa524a0..ea0e1de8f35 100755 --- a/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java +++ b/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java @@ -32,6 +32,7 @@ public interface Duration extends Serializable, Comparable { Duration divide(long divisor); Duration divide(double divisor); + double divide(Duration duration); Duration times(long factor); Duration times(double factor); diff --git a/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java b/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java index 817442d27c8..a42de4256a2 100755 --- a/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java +++ b/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java @@ -33,6 +33,11 @@ public class MillisecondsDurationImpl implements Duration { return new MillisecondsDurationImpl((long) (1. / divisor * asMillis())); } + @Override + public double divide(Duration duration) { + return ((double) asMillis()) / (double) duration.asMillis(); + } + @Override public Duration times(long factor) { return new MillisecondsDurationImpl(asMillis() * factor);