fixed delayed delivery of mark passing events; using a Timer; seems to roughly work. Now profiling needs to be done.

This commit is contained in:
Axel Uhl committed 2012-06-19 00:44:34 +02:00
1 parent 4c0b69e71d
commit 51f7e32f7e
3 files changed
+101 -14

No files matched your search

@@ -75,9 +75,6 @@ public class MarkPassingReceiver extends AbstractReceiverWithQueue<RaceCompetito
getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()));
if (passed != null) {
TimePoint time = new MillisecondsTimePoint(passing.getTimestamp());
if (getSimulator() != null) {
time = getSimulator().delayMarkPassingTimePoint(time);
}
MarkPassing markPassing = getDomainFactory().createMarkPassing(time, passed,
getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()));
passingsByWaypoint.put(passed, markPassing);
@@ -93,8 +90,12 @@ public class MarkPassingReceiver extends AbstractReceiverWithQueue<RaceCompetito
markPassings.add(passing);
}
}
trackedRace.updateMarkPassings(getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()),
markPassings);
if (getSimulator() != null) {
getSimulator().delayMarkPassings(getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()), markPassings);
} else {
trackedRace.updateMarkPassings(getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()),
markPassings);
}
} else {
logger.warning("Couldn't find tracked race for race " + event.getA().getRace().getName()
+ ". Dropping mark passing event " + event);
@@ -17,7 +17,6 @@ import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.tractrac.clientmodule.ControlPoint;
import com.tractrac.clientmodule.Race;
@@ -115,10 +114,10 @@ public class MarkPositionReceiver extends AbstractReceiverWithQueue<ControlPoint
if (trackedRace != null) {
GPSFixMoving markPosition = getDomainFactory().createGPSFixMoving(event.getB());
if (getSimulator() != null) {
markPosition = new GPSFixMovingImpl(markPosition.getPosition(), getSimulator().delay(
markPosition.getTimePoint()), markPosition.getSpeed());
getSimulator().scheduleMarkPosition(buoy, markPosition);
} else {
trackedRace.recordFix(buoy, markPosition);
}
trackedRace.recordFix(buoy, markPosition);
} else {
logger.warning("Couldn't find tracked race for race " + tractracRace.getName()
+ ". Dropping mark position event " + event);
@@ -1,17 +1,28 @@
package com.sap.sailing.domain.tractracadapter.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.Buoy;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
import com.sap.sailing.domain.tracking.impl.WindImpl;
public class Simulator {
@@ -20,6 +31,8 @@ public class Simulator {
private DynamicTrackedRace trackedRace;
private WindStore windStore;
private long advanceInMillis = -1;
private Timer timer = new Timer("Timer for TracTrac Simulator");
/**
* Creates a wind store which replays the wind store events against a tracked race, correcting the wind fixes with
* the simulation delay. The wind store returned is an {@link EmptyWindStore}.
@@ -90,9 +103,8 @@ public class Simulator {
* has passed. Then, returns the adjusted time point which therefore should roughly equal "now."
*/
public TimePoint delay(TimePoint timePoint) {
long now = System.currentTimeMillis();
TimePoint transformedTimed = advance(timePoint);
long waitTimeInMillis = transformedTimed.asMillis() - now;
long waitTimeInMillis = getWaitTimeInMillisUntil(transformedTimed);
do {
if (waitTimeInMillis > 0) {
try {
@@ -107,6 +119,12 @@ public class Simulator {
return transformedTimed;
}
private long getWaitTimeInMillisUntil(TimePoint transformedTimepoint) {
long now = System.currentTimeMillis();
long waitTimeInMillis = transformedTimepoint.asMillis() - now;
return waitTimeInMillis;
}
/**
* Like {@link #delay}, only that it doesn't wait until <code>timePoint</code> is reached in wall time.
*/
@@ -119,16 +137,85 @@ public class Simulator {
* Otherwise, <code>time</code> is taken to be the original start time of the race which is then used to compute
* {@link #advanceInMillis} such that <code>time.asMillis() + advanceInMillis == System.currentTimeMillis()</code>.
*/
public TimePoint delayMarkPassingTimePoint(TimePoint time) {
public TimePoint advanceMarkPassingTimePoint(TimePoint time) {
if (isAdvanceInMilliseSet()) {
return delay(time);
return advance(time);
} else {
setAdvanceInMillis(System.currentTimeMillis() - time.asMillis());
return delay(time);
return advance(time);
}
}
private boolean isAdvanceInMilliseSet() {
return advanceInMillis != -1;
}
/**
* Delivers those mark passings for which we don't have to wait as a single list to the {@link #trackedRace} now.
* The remaining mark passings are delayed as long as it takes for the first mark passing with a positive wait time
* to match "now." The whole list is then re-submitted to this same method.
*/
public void delayMarkPassings(final Competitor competitor, List<MarkPassing> markPassings) {
List<MarkPassing> deliverTransformedNow = new ArrayList<MarkPassing>();
final List<MarkPassing> deliverLater = new ArrayList<MarkPassing>();
Iterator<MarkPassing> i = markPassings.iterator();
if (i.hasNext()) {
MarkPassing markPassing = i.next();
deliverLater.add(markPassing);
TimePoint transformedTimepoint = advanceMarkPassingTimePoint(markPassing.getTimePoint());
while (getWaitTimeInMillisUntil(transformedTimepoint) <= 0 && markPassing != null) {
MarkPassing transformedMarkPassing = new MarkPassingImpl(transformedTimepoint,
markPassing.getWaypoint(), markPassing.getCompetitor());
deliverTransformedNow.add(transformedMarkPassing);
if (i.hasNext()) {
markPassing = i.next();
transformedTimepoint = advanceMarkPassingTimePoint(markPassing.getTimePoint());
deliverLater.add(markPassing);
} else {
markPassing = null;
}
}
trackedRace.updateMarkPassings(competitor, deliverTransformedNow);
if (markPassing != null) {
// not consumed and delivered all mark passings now
while (i.hasNext()) {
deliverLater.add(i.next());
}
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
delayMarkPassings(competitor, deliverLater);
} catch (Throwable t) {
logger.throwing(Simulator.class.getName(), "scheduleMarkPosition", t);
}
}
}, transformedTimepoint.asDate());
}
} else {
// deliver an empty list now
trackedRace.updateMarkPassings(competitor, markPassings);
}
}
public void scheduleMarkPosition(final Buoy buoy, GPSFixMoving markFix) {
final TimePoint transformedTimepoint = advance(markFix.getTimePoint());
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(markFix.getPosition(), transformedTimepoint, markFix.getSpeed());
long waitTime = getWaitTimeInMillisUntil(transformedMarkFix.getTimePoint());
if (waitTime <= 0) {
trackedRace.recordFix(buoy, transformedMarkFix);
} else {
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
trackedRace.recordFix(buoy, transformedMarkFix);
} catch (Throwable t) {
logger.throwing(Simulator.class.getName(), "scheduleMarkPosition", t);
}
}
}, transformedTimepoint.asDate());
}
}
}