mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-22 13:45:42 +00:00
Merge branch 'master' of ssh://sapsailing.com/home/trac/git
This commit is contained in:
+13
@@ -1301,4 +1301,17 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
public TrackingConnectorInfo getTrackingConnectorInfo() {
|
public TrackingConnectorInfo getTrackingConnectorInfo() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWhenDoneLoading(Runnable runnable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runSynchronizedOnStatus(Runnable runnable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFinishedLoading() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -814,4 +814,16 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWhenDoneLoading(Runnable runnable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runSynchronizedOnStatus(Runnable runnable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFinishedLoading() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-1
@@ -65,7 +65,6 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
|
|||||||
public DummyTrackedRace(final Map<Competitor, Boat> competitors, final Regatta regatta, final TrackedRegatta trackedRegatta,
|
public DummyTrackedRace(final Map<Competitor, Boat> competitors, final Regatta regatta, final TrackedRegatta trackedRegatta,
|
||||||
RaceDefinition race) {
|
RaceDefinition race) {
|
||||||
this(competitors, regatta, trackedRegatta, race, EmptyWindStore.INSTANCE);
|
this(competitors, regatta, trackedRegatta, race, EmptyWindStore.INSTANCE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DummyTrackedRace(final String raceName, final Serializable raceId) {
|
public DummyTrackedRace(final String raceName, final Serializable raceId) {
|
||||||
@@ -750,4 +749,17 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
|
|||||||
public TrackingConnectorInfo getTrackingConnectorInfo() {
|
public TrackingConnectorInfo getTrackingConnectorInfo() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWhenDoneLoading(Runnable runnable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runSynchronizedOnStatus(Runnable runnable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFinishedLoading() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1256,4 +1256,28 @@ public interface TrackedRace
|
|||||||
* may be {@code null}, particularly in test set-ups
|
* may be {@code null}, particularly in test set-ups
|
||||||
*/
|
*/
|
||||||
TrackingConnectorInfo getTrackingConnectorInfo();
|
TrackingConnectorInfo getTrackingConnectorInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Under synchronization with the {@link #getStatus() race status} checks if the race {@link #hasFinishedLoading()
|
||||||
|
* has already finished loading}. If so, {@code runnable} is invoked. Otherwise, a {@link RaceChangeListener} is
|
||||||
|
* {@link #addListener(RaceChangeListener) added} to this race, observing the race status and calling
|
||||||
|
* {@code runnable} when the race has finished loading.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* A race is considered to have finished loading when it is not in either of the states
|
||||||
|
* {@link TrackedRaceStatusEnum#PREPARED}, {@link TrackedRaceStatusEnum#LOADING}, or
|
||||||
|
* {@link TrackedRaceStatusEnum#ERROR}.
|
||||||
|
*
|
||||||
|
* @param runnable
|
||||||
|
* must not be {@code null}
|
||||||
|
*/
|
||||||
|
void runWhenDoneLoading(Runnable runnable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the {@code callable} under synchronization with the {@link #getStatus() race status}; in other words,
|
||||||
|
* while the callable executes, the race status of this race cannot be updated.
|
||||||
|
*/
|
||||||
|
void runSynchronizedOnStatus(Runnable runnable);
|
||||||
|
|
||||||
|
boolean hasFinishedLoading();
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-3
@@ -2919,13 +2919,18 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes to the {@link #status} variable are synchronized on the {@link #statusNotifier} field.
|
* Changes to the {@link #status} variable are synchronized on the {@link #statusNotifier} field
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
protected Object getStatusNotifier() {
|
protected Object getStatusNotifier() {
|
||||||
return statusNotifier;
|
return statusNotifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runSynchronizedOnStatus(Runnable runnable) {
|
||||||
|
synchronized (getStatusNotifier()) {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void setStatus(TrackedRaceStatus newStatus) {
|
protected void setStatus(TrackedRaceStatus newStatus) {
|
||||||
assert newStatus != null;
|
assert newStatus != null;
|
||||||
@@ -2994,6 +2999,37 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFinishedLoading() {
|
||||||
|
synchronized (getStatusNotifier()) {
|
||||||
|
final TrackedRaceStatusEnum status = getStatus().getStatus();
|
||||||
|
return hasFinishedLoading(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasFinishedLoading(TrackedRaceStatusEnum status) {
|
||||||
|
return (status != TrackedRaceStatusEnum.PREPARED && status != TrackedRaceStatusEnum.LOADING && status != TrackedRaceStatusEnum.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWhenDoneLoading(final Runnable runnable) {
|
||||||
|
synchronized (getStatusNotifier()) {
|
||||||
|
if (!hasFinishedLoading()) {
|
||||||
|
addListener(new AbstractRaceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void statusChanged(TrackedRaceStatus newStatus, TrackedRaceStatus oldStatus) {
|
||||||
|
if (hasFinishedLoading(newStatus.getStatus())) {
|
||||||
|
removeListener(this);
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attachRaceLog(RaceLog raceLog) {
|
public void attachRaceLog(RaceLog raceLog) {
|
||||||
synchronized (TrackedRaceImpl.this) {
|
synchronized (TrackedRaceImpl.this) {
|
||||||
|
|||||||
+16
-4
@@ -19,6 +19,7 @@ import com.sap.sse.replication.ReplicationService;
|
|||||||
import com.sap.sse.replication.ReplicationStatus;
|
import com.sap.sse.replication.ReplicationStatus;
|
||||||
|
|
||||||
public class StatusServlet extends HttpServlet {
|
public class StatusServlet extends HttpServlet {
|
||||||
|
private static final String WAIT_UNTIL_RACES_LOADED = "waitUntilRacesLoaded";
|
||||||
private static final long serialVersionUID = -8896724182560416457L;
|
private static final long serialVersionUID = -8896724182560416457L;
|
||||||
|
|
||||||
protected <T> T getService(Class<T> clazz) {
|
protected <T> T getService(Class<T> clazz) {
|
||||||
@@ -43,15 +44,26 @@ public class StatusServlet extends HttpServlet {
|
|||||||
final ServletContext servletContext = req.getServletContext();
|
final ServletContext servletContext = req.getServletContext();
|
||||||
final JSONObject result = new JSONObject();
|
final JSONObject result = new JSONObject();
|
||||||
final RacingEventService service = getService(servletContext);
|
final RacingEventService service = getService(servletContext);
|
||||||
result.put("numberofracestorestore", service.getNumberOfTrackedRacesToRestore());
|
final String waitUntilRacesLoadedString = req.getParameter(WAIT_UNTIL_RACES_LOADED);
|
||||||
result.put("numberofracesrestored", service.getNumberOfTrackedRacesRestored());
|
boolean waitUntilRacesLoaded = Boolean.valueOf(waitUntilRacesLoadedString);
|
||||||
|
final long numberOfTrackedRacesToRestore = service.getNumberOfTrackedRacesToRestore();
|
||||||
|
result.put("numberofracestorestore", numberOfTrackedRacesToRestore);
|
||||||
|
final int numberOfTrackedRacesRestored = service.getNumberOfTrackedRacesRestored();
|
||||||
|
result.put("numberofracesrestored", numberOfTrackedRacesRestored);
|
||||||
|
final int numberOfTrackedRacesRestoredDoneLoading = service.getNumberOfTrackedRacesRestoredDoneLoading();
|
||||||
|
result.put("numberofracesrestoreddoneloading", numberOfTrackedRacesRestoredDoneLoading);
|
||||||
|
final int numberOfTrackedRacesStillLoading = service.getNumberOfTrackedRacesStillLoading();
|
||||||
|
result.put("numberofracesstillloading", numberOfTrackedRacesStillLoading);
|
||||||
final ReplicationService replicationService = getReplicationService(servletContext);
|
final ReplicationService replicationService = getReplicationService(servletContext);
|
||||||
final ReplicationStatus replicationStatus = replicationService == null ? null : replicationService.getStatus();
|
final ReplicationStatus replicationStatus = replicationService == null ? null : replicationService.getStatus();
|
||||||
if (replicationStatus != null) {
|
if (replicationStatus != null) {
|
||||||
result.put("replication", replicationStatus.toJSONObject());
|
result.put("replication", replicationStatus.toJSONObject());
|
||||||
}
|
}
|
||||||
final boolean available = service.getNumberOfTrackedRacesRestored() >= service.getNumberOfTrackedRacesToRestore() &&
|
boolean available = numberOfTrackedRacesRestored >= numberOfTrackedRacesToRestore
|
||||||
(replicationStatus == null || replicationStatus.isAvailable());
|
&& (replicationStatus == null || replicationStatus.isAvailable());
|
||||||
|
if (waitUntilRacesLoaded) {
|
||||||
|
available = available && numberOfTrackedRacesRestoredDoneLoading == numberOfTrackedRacesToRestore;
|
||||||
|
}
|
||||||
result.put("available", available);
|
result.put("available", available);
|
||||||
resp.setStatus(available ? HttpServletResponse.SC_OK : HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
resp.setStatus(available ? HttpServletResponse.SC_OK : HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
||||||
resp.setContentType(MediaType.APPLICATION_JSON + ";charset=UTF-8");
|
resp.setContentType(MediaType.APPLICATION_JSON + ";charset=UTF-8");
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ Availability will be reported as "true" if all races to be restored have
|
|||||||
appeared. There may still be some data retrieval going on, so for the server
|
appeared. There may still be some data retrieval going on, so for the server
|
||||||
truly to be available, after having received available:true for the first time,
|
truly to be available, after having received available:true for the first time,
|
||||||
add some leeway that corresponds to the typical race load time.</p>
|
add some leeway that corresponds to the typical race load time.</p>
|
||||||
|
<p>You can request to obtain available:true only in case all races that are to be restored
|
||||||
|
have finished loading. For this, set the <tt>waitUntilRacesLoaded</tt> parameter to <tt>true</tt>.</p>
|
||||||
<p>Furthermore, consider the "replica" attribute in the response. It may start
|
<p>Furthermore, consider the "replica" attribute in the response. It may start
|
||||||
out as "false" although initial replication has been requested. See also the
|
out as "false" although initial replication has been requested. See also the
|
||||||
<tt>/replication/replication?action=STATUS</tt> API which provide comprehensive
|
<tt>/replication/replication?action=STATUS</tt> API which provide comprehensive
|
||||||
@@ -43,7 +45,9 @@ with the "replica" attribute, and if it is "false" check this endpoint.
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Optional parameters:</td>
|
<td>Optional parameters:</td>
|
||||||
<td>None</td>
|
<td>waitUntilRacesLoaded: if <tt>true</tt>, the overall status will be reported
|
||||||
|
as available only if all races that are to be restored have also finished
|
||||||
|
their loading process and moved to state TRACKING, FINISHED, or ERROR.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Request method:</td>
|
<td>Request method:</td>
|
||||||
@@ -59,13 +63,57 @@ with the "replica" attribute, and if it is "false" check this endpoint.
|
|||||||
<td>Example Response:</td>
|
<td>Example Response:</td>
|
||||||
<td>
|
<td>
|
||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"numberofracestorestore": 12847,
|
"numberofracestorestore": 48,
|
||||||
"numberofracesrestored": 12847,
|
"numberofracesrestored": 48,
|
||||||
"isreplica": false,
|
"numberofracesrestoreddoneloading": 48,
|
||||||
"initialloadrunning": false,
|
"numberofracesstillloading": 0,
|
||||||
"available": true
|
"replication": {
|
||||||
}
|
"replica": false,
|
||||||
|
"replicationstarting": false,
|
||||||
|
"suspended": false,
|
||||||
|
"stopped": false,
|
||||||
|
"messagequeuelength": 0,
|
||||||
|
"operationqueuelengths": [],
|
||||||
|
"totaloperationqueuelength": 0,
|
||||||
|
"replicables": [
|
||||||
|
{
|
||||||
|
"id": "com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl",
|
||||||
|
"initialloadrunning": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "com.sap.sailing.shared.server.impl.SharedSailingDataImpl",
|
||||||
|
"initialloadrunning": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "com.sap.sse.mail.impl.MailServiceImpl",
|
||||||
|
"initialloadrunning": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "com.sap.sailing.domain.racelogtracking.impl.fixtracker.RegattaLogFixTrackerRegattaListener",
|
||||||
|
"initialloadrunning": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "com.sap.sailing.polars.impl.PolarDataServiceImpl",
|
||||||
|
"initialloadrunning": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "com.sap.sse.security.impl.SecurityServiceImpl",
|
||||||
|
"initialloadrunning": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "com.sap.sailing.windestimation.integration.WindEstimationFactoryServiceImpl",
|
||||||
|
"initialloadrunning": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "com.sap.sailing.server.impl.RacingEventServiceImpl",
|
||||||
|
"initialloadrunning": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"available": true
|
||||||
|
},
|
||||||
|
"available": true
|
||||||
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
+11
@@ -965,4 +965,15 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
|||||||
void addOrReplaceExpeditionDeviceConfiguration(UUID deviceConfigurationId, String name, Integer expeditionBoatId);
|
void addOrReplaceExpeditionDeviceConfiguration(UUID deviceConfigurationId, String name, Integer expeditionBoatId);
|
||||||
|
|
||||||
void removeExpeditionDeviceConfiguration(UUID deviceUuid);
|
void removeExpeditionDeviceConfiguration(UUID deviceUuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of tracked races that are not {@link TrackedRace#hasFinishedLoading() done with loading}.
|
||||||
|
*/
|
||||||
|
int getNumberOfTrackedRacesStillLoading();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of tracked races restored during server start-up that are
|
||||||
|
* {@link TrackedRace#hasFinishedLoading() done with loading}.
|
||||||
|
*/
|
||||||
|
int getNumberOfTrackedRacesRestoredDoneLoading();
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-31
@@ -438,7 +438,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
/**
|
/**
|
||||||
* A set based on a concurrent hash map, therefore being thread safe
|
* A set based on a concurrent hash map, therefore being thread safe
|
||||||
*/
|
*/
|
||||||
private Set<DynamicTrackedRegatta> regattasObservedForDefaultLeaderboard = Collections
|
private Set<DynamicTrackedRegatta> regattasObservedWithRaceAdditionListener = Collections
|
||||||
.newSetFromMap(new ConcurrentHashMap<DynamicTrackedRegatta, Boolean>());
|
.newSetFromMap(new ConcurrentHashMap<DynamicTrackedRegatta, Boolean>());
|
||||||
|
|
||||||
private final MongoObjectFactory mongoObjectFactory;
|
private final MongoObjectFactory mongoObjectFactory;
|
||||||
@@ -555,6 +555,10 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
|
|
||||||
private final AtomicInteger numberOfTrackedRacesRestored;
|
private final AtomicInteger numberOfTrackedRacesRestored;
|
||||||
|
|
||||||
|
private final AtomicInteger numberOfTrackedRacesRestoredDoneLoading;
|
||||||
|
|
||||||
|
private final AtomicInteger numberOfTrackedRacesStillLoading;
|
||||||
|
|
||||||
private final ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> resultUrlRegistryServiceTracker;
|
private final ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> resultUrlRegistryServiceTracker;
|
||||||
|
|
||||||
private final ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider> scoreCorrectionProviderServiceTracker;
|
private final ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider> scoreCorrectionProviderServiceTracker;
|
||||||
@@ -804,6 +808,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
this.currentlyFillingFromInitialLoad = false;
|
this.currentlyFillingFromInitialLoad = false;
|
||||||
this.securityServiceTracker = securityServiceTracker;
|
this.securityServiceTracker = securityServiceTracker;
|
||||||
this.numberOfTrackedRacesRestored = new AtomicInteger();
|
this.numberOfTrackedRacesRestored = new AtomicInteger();
|
||||||
|
this.numberOfTrackedRacesRestoredDoneLoading = new AtomicInteger();
|
||||||
|
this.numberOfTrackedRacesStillLoading = new AtomicInteger();
|
||||||
this.resultUrlRegistryServiceTracker = resultUrlRegistryServiceTracker;
|
this.resultUrlRegistryServiceTracker = resultUrlRegistryServiceTracker;
|
||||||
this.scoreCorrectionProviderServiceTracker = scoreCorrectionProviderServiceTracker;
|
this.scoreCorrectionProviderServiceTracker = scoreCorrectionProviderServiceTracker;
|
||||||
this.scoreCorrectionListenersByLeaderboard = new ConcurrentHashMap<>();
|
this.scoreCorrectionListenersByLeaderboard = new ConcurrentHashMap<>();
|
||||||
@@ -935,24 +941,26 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
numberOfTrackedRacesToRestore = getDomainObjectFactory().loadConnectivityParametersForRacesToRestore(params -> {
|
numberOfTrackedRacesToRestore = getDomainObjectFactory().loadConnectivityParametersForRacesToRestore(params -> {
|
||||||
try {
|
try {
|
||||||
final RaceHandle handle = addRace(/* addToRegatta==null means "default regatta" */ null, params, /* no timeout during mass loading */ -1,
|
final RaceHandle handle = addRace(/* addToRegatta==null means "default regatta" */ null, params, /* no timeout during mass loading */ -1,
|
||||||
new DefaultRaceTrackingHandler() {
|
new DefaultRaceTrackingHandler() {
|
||||||
@Override
|
@Override
|
||||||
public DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta,
|
public DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta,
|
||||||
RaceDefinition raceDefinition, Iterable<Sideline> sidelines, WindStore windStore,
|
RaceDefinition raceDefinition, Iterable<Sideline> sidelines, WindStore windStore,
|
||||||
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
|
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
|
||||||
long millisecondsOverWhichToAverageSpeed,
|
long millisecondsOverWhichToAverageSpeed,
|
||||||
DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
|
DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
|
||||||
boolean useMarkPassingCalculator, RaceLogAndTrackedRaceResolver raceLogResolver,
|
boolean useMarkPassingCalculator, RaceLogAndTrackedRaceResolver raceLogResolver,
|
||||||
Optional<ThreadLocalTransporter> threadLocalTransporter,
|
Optional<ThreadLocalTransporter> threadLocalTransporter,
|
||||||
TrackingConnectorInfo trackingConnectorInfo) {
|
TrackingConnectorInfo trackingConnectorInfo) {
|
||||||
final DynamicTrackedRace trackedRace = super.createTrackedRace(trackedRegatta, raceDefinition, sidelines, windStore,
|
final DynamicTrackedRace trackedRace = super.createTrackedRace(trackedRegatta, raceDefinition, sidelines, windStore,
|
||||||
delayToLiveInMillis, millisecondsOverWhichToAverageWind,
|
delayToLiveInMillis, millisecondsOverWhichToAverageWind,
|
||||||
millisecondsOverWhichToAverageSpeed, raceDefinitionSetToUpdate,
|
millisecondsOverWhichToAverageSpeed, raceDefinitionSetToUpdate,
|
||||||
useMarkPassingCalculator, raceLogResolver, threadLocalTransporter, trackingConnectorInfo);
|
useMarkPassingCalculator, raceLogResolver, threadLocalTransporter, trackingConnectorInfo);
|
||||||
getSecurityService().migrateOwnership(trackedRace);
|
getSecurityService().migrateOwnership(trackedRace);
|
||||||
return trackedRace;
|
trackedRace.runWhenDoneLoading(
|
||||||
}
|
()->numberOfTrackedRacesRestoredDoneLoading.incrementAndGet());
|
||||||
});
|
return trackedRace;
|
||||||
|
}
|
||||||
|
});
|
||||||
final RaceDefinition race = handle.getRace(RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); // try to not flood servers during restore by waiting for race to appear
|
final RaceDefinition race = handle.getRace(RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); // try to not flood servers during restore by waiting for race to appear
|
||||||
if (race == null) {
|
if (race == null) {
|
||||||
logger.warning("Race for tracker " + handle.getRaceTracker() + " with ID "
|
logger.warning("Race for tracker " + handle.getRaceTracker() + " with ID "
|
||||||
@@ -2066,9 +2074,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
trackingConnectorInfo);
|
trackingConnectorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureRegattaIsObservedForDefaultLeaderboardAndAutoLeaderboardLinking(
|
private void ensureRegattaHasRaceAdditionListener(DynamicTrackedRegatta trackedRegatta) {
|
||||||
DynamicTrackedRegatta trackedRegatta) {
|
if (regattasObservedWithRaceAdditionListener.add(trackedRegatta)) {
|
||||||
if (regattasObservedForDefaultLeaderboard.add(trackedRegatta)) {
|
|
||||||
trackedRegatta.addRaceListener(new RaceAdditionListener(),
|
trackedRegatta.addRaceListener(new RaceAdditionListener(),
|
||||||
/* ThreadLocalTransporter */ Optional.empty(), // registering for synchronous callbacks; no thread locals need to be transported
|
/* ThreadLocalTransporter */ Optional.empty(), // registering for synchronous callbacks; no thread locals need to be transported
|
||||||
/* register for synchronous execution in order to ensure that any replication-related effects happen before
|
/* register for synchronous execution in order to ensure that any replication-related effects happen before
|
||||||
@@ -2077,8 +2084,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopObservingRegattaForRedaultLeaderboardAndAutoLeaderboardLinking(DynamicTrackedRegatta trackedRegatta) {
|
private void stopObservingRegattaWithRaceAdditionListener(DynamicTrackedRegatta trackedRegatta) {
|
||||||
regattasObservedForDefaultLeaderboard.remove(trackedRegatta);
|
regattasObservedWithRaceAdditionListener.remove(trackedRegatta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2086,11 +2093,19 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
* service, the service adds the tracked race to the default leaderboard and links it to the leaderboard columns
|
* service, the service adds the tracked race to the default leaderboard and links it to the leaderboard columns
|
||||||
* that were previously connected to it. Additionally, a {@link RaceChangeListener} is added to the
|
* that were previously connected to it. Additionally, a {@link RaceChangeListener} is added to the
|
||||||
* {@link TrackedRace} which is responsible for triggering the replication of all relevant changes to the tracked
|
* {@link TrackedRace} which is responsible for triggering the replication of all relevant changes to the tracked
|
||||||
* race. When a tracked race is removed, the {@link TrackedRaceReplicatorAndNotifier} that was added as listener to that
|
* race. When a tracked race is removed, the {@link TrackedRaceReplicatorAndNotifier} that was added as listener to
|
||||||
* tracked race is removed again.
|
* that tracked race is removed again.
|
||||||
|
* <p>
|
||||||
*
|
*
|
||||||
* A {@link PolarFixCacheUpdater} is added to every race so that polar fixes are aggregated when new GPS fixes
|
* A {@link PolarFixCacheUpdater} is added to every race so that polar fixes are aggregated when new GPS fixes
|
||||||
* arrive.
|
* arrive.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* Furthermore, the {@link RacingEventServiceImpl#numberOfTrackedRacesStillLoading} counter is adjusted based
|
||||||
|
* on the {@link TrackedRace#getStatus() race status}. If a tracked race is removed and it hasn't been fully loaded
|
||||||
|
* yet, the counter is decremented. If a new race is added, the counter is incremented and a function will be
|
||||||
|
* {@link TrackedRace#runWhenDoneLoading(Runnable) executed when the race is fully loaded} which will decrement
|
||||||
|
* it again.
|
||||||
*
|
*
|
||||||
* @author Axel Uhl (d043530)
|
* @author Axel Uhl (d043530)
|
||||||
*
|
*
|
||||||
@@ -2117,6 +2132,11 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
if (polarFixCacheUpdater != null) {
|
if (polarFixCacheUpdater != null) {
|
||||||
trackedRace.removeListener(polarFixCacheUpdater);
|
trackedRace.removeListener(polarFixCacheUpdater);
|
||||||
}
|
}
|
||||||
|
trackedRace.runSynchronizedOnStatus(()->{
|
||||||
|
if (!trackedRace.hasFinishedLoading()) {
|
||||||
|
numberOfTrackedRacesStillLoading.decrementAndGet();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2140,6 +2160,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
trackedRace.setWindEstimation(
|
trackedRace.setWindEstimation(
|
||||||
windEstimationFactoryService.createIncrementalWindEstimationTrack(trackedRace));
|
windEstimationFactoryService.createIncrementalWindEstimationTrack(trackedRace));
|
||||||
}
|
}
|
||||||
|
numberOfTrackedRacesStillLoading.incrementAndGet();
|
||||||
|
trackedRace.runWhenDoneLoading(()->numberOfTrackedRacesStillLoading.decrementAndGet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2955,7 +2977,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
result = new DynamicTrackedRegattaImpl(regatta);
|
result = new DynamicTrackedRegattaImpl(regatta);
|
||||||
replicate(new TrackRegatta(regatta.getRegattaIdentifier()));
|
replicate(new TrackRegatta(regatta.getRegattaIdentifier()));
|
||||||
regattaTrackingCache.put(regatta, result);
|
regattaTrackingCache.put(regatta, result);
|
||||||
ensureRegattaIsObservedForDefaultLeaderboardAndAutoLeaderboardLinking(result);
|
ensureRegattaHasRaceAdditionListener(result);
|
||||||
trackedRegattaListener.regattaAdded(result);
|
trackedRegattaListener.regattaAdded(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -2979,7 +3001,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
} finally {
|
} finally {
|
||||||
LockUtil.unlockAfterWrite(regattaTrackingCacheLock);
|
LockUtil.unlockAfterWrite(regattaTrackingCacheLock);
|
||||||
}
|
}
|
||||||
stopObservingRegattaForRedaultLeaderboardAndAutoLeaderboardLinking(trackedRegatta);
|
stopObservingRegattaWithRaceAdditionListener(trackedRegatta);
|
||||||
trackedRegattaListener.regattaRemoved(trackedRegatta);
|
trackedRegattaListener.regattaRemoved(trackedRegatta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3294,7 +3316,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Serializing regattas observed...");
|
logger.info("Serializing regattas observed...");
|
||||||
oos.writeObject(regattasObservedForDefaultLeaderboard);
|
oos.writeObject(regattasObservedWithRaceAdditionListener);
|
||||||
logger.info("Serializing regatta tracking cache...");
|
logger.info("Serializing regatta tracking cache...");
|
||||||
oos.writeObject(regattaTrackingCache);
|
oos.writeObject(regattaTrackingCache);
|
||||||
logger.info("Serializing leaderboard groups...");
|
logger.info("Serializing leaderboard groups...");
|
||||||
@@ -3380,7 +3402,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
// old leaderboards takes place which then don't match the new ones
|
// old leaderboards takes place which then don't match the new ones
|
||||||
logger.info("Reading all dynamic tracked regattas...");
|
logger.info("Reading all dynamic tracked regattas...");
|
||||||
for (DynamicTrackedRegatta trackedRegattaToObserve : (Set<DynamicTrackedRegatta>) ois.readObject()) {
|
for (DynamicTrackedRegatta trackedRegattaToObserve : (Set<DynamicTrackedRegatta>) ois.readObject()) {
|
||||||
ensureRegattaIsObservedForDefaultLeaderboardAndAutoLeaderboardLinking(trackedRegattaToObserve);
|
ensureRegattaHasRaceAdditionListener(trackedRegattaToObserve);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Reading all of the regatta tracking cache...");
|
logger.info("Reading all of the regatta tracking cache...");
|
||||||
@@ -3509,7 +3531,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
} finally {
|
} finally {
|
||||||
LockUtil.unlockAfterWrite(regattasByNameLock);
|
LockUtil.unlockAfterWrite(regattasByNameLock);
|
||||||
}
|
}
|
||||||
regattasObservedForDefaultLeaderboard.clear();
|
regattasObservedWithRaceAdditionListener.clear();
|
||||||
|
|
||||||
if (raceTrackersByRegatta != null && !raceTrackersByRegatta.isEmpty()) {
|
if (raceTrackersByRegatta != null && !raceTrackersByRegatta.isEmpty()) {
|
||||||
for (DynamicTrackedRegatta regatta : regattaTrackingCache.values()) {
|
for (DynamicTrackedRegatta regatta : regattaTrackingCache.values()) {
|
||||||
@@ -5125,4 +5147,14 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfTrackedRacesStillLoading() {
|
||||||
|
return numberOfTrackedRacesStillLoading.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfTrackedRacesRestoredDoneLoading() {
|
||||||
|
return numberOfTrackedRacesRestoredDoneLoading.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
|||||||
# Overwrite the log leves for specific loggers here
|
# Overwrite the log leves for specific loggers here
|
||||||
com.sap.sailing.level = FINE
|
com.sap.sailing.level = FINE
|
||||||
com.sap.sse.level = FINE
|
com.sap.sse.level = FINE
|
||||||
com.sap.sailing.domain.markpassingcalculation.level = FINEST
|
#com.sap.sailing.domain.markpassingcalculation.level = FINEST
|
||||||
|
com.sap.sailing.domain.markpassingcalculation.level = INFO
|
||||||
# log at level FINEST for TransientCompetitorStoreIMpl
|
# log at level FINEST for TransientCompetitorStoreIMpl
|
||||||
#com.sap.sailing.domain.base.impl.TransientCompetitorStoreImpl.level = FINEST
|
#com.sap.sailing.domain.base.impl.TransientCompetitorStoreImpl.level = FINEST
|
||||||
#com.sap.sailing.domain.base.impl.SharedDomainFactoryImpl.level = FINEST
|
#com.sap.sailing.domain.base.impl.SharedDomainFactoryImpl.level = FINEST
|
||||||
|
|||||||
Reference in New Issue
Block a user