clear server state entirely before starting to import initial load;

particularly registering the replica service for tracked race additions in order to auto-link them
to leaderboards causes trouble if the server state is not cleared before. Replicated tracked races may
then get auto-linked to old leaderboards and regattas in the server that happen to point to races with
equal RaceIdentifiers.

Also, it is important to become tolerant against a non-existing default leaderboard which doesn't exist
yet when tracked races are imported. The default leaderboard will be replicated together with other
leaderboards.
This commit is contained in:
Axel Uhl
2012-06-15 01:43:07 +02:00
parent d7ca838eb6
commit eb7a8f4050
3 changed files with 23 additions and 8 deletions
@@ -14,7 +14,8 @@ Export-Package: com.sap.sailing.domain.base,
com.sap.sailing.domain.leaderboard.impl,
com.sap.sailing.domain.tracking,
com.sap.sailing.domain.tracking.impl,
com.sap.sailing.util
com.sap.sailing.util,
com.sap.sailing.util.impl;x-friends:="com.sap.sailing.server.replication"
Bundle-ActivationPolicy: lazy
Require-Bundle: com.googlecode.java-diff-utils;bundle-version="1.3.0",
com.sap.sailing.domain.common,
@@ -5,6 +5,7 @@ import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.logging.Logger;
import javax.jms.JMSException;
import javax.servlet.ServletException;
@@ -27,6 +28,8 @@ import com.sap.sailing.server.replication.ReplicaDescriptor;
*
*/
public class ReplicationServlet extends Servlet {
private static final Logger logger = Logger.getLogger(ReplicationServlet.class.getName());
private static final long serialVersionUID = 4835516998934433846L;
public enum Action { REGISTER, INITIAL_LOAD }
@@ -65,7 +68,14 @@ public class ReplicationServlet extends Servlet {
break;
case INITIAL_LOAD:
ObjectOutputStream oos = new ObjectOutputStream(resp.getOutputStream());
getService().serializeForInitialReplication(oos);
try {
getService().serializeForInitialReplication(oos);
} catch (Exception e) {
logger.info("Error trying to serialize initial load for replication: "+e.getMessage());
logger.throwing(ReplicationServlet.class.getName(), "doGet", e);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
e.printStackTrace(resp.getWriter());
}
break;
default:
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Action " + action + " not understood. Must be one of "
@@ -776,8 +776,10 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
replicate(op);
linkRaceToConfiguredLeaderboardColumns(trackedRace);
final FlexibleLeaderboard defaultLeaderboard = (FlexibleLeaderboard) leaderboardsByName.get(DefaultLeaderboardName.DEFAULT_LEADERBOARD_NAME);
defaultLeaderboard.addRace(trackedRace,
trackedRace.getRace().getName(), /* medalRace */false, defaultLeaderboard.getFleet(null));
if (defaultLeaderboard != null) {
defaultLeaderboard.addRace(trackedRace, trackedRace.getRace().getName(), /* medalRace */false,
defaultLeaderboard.getFleet(null));
}
TrackedRaceReplicator trackedRaceReplicator = new TrackedRaceReplicator(trackedRace);
trackedRaceReplicators.put(trackedRace, trackedRaceReplicator);
trackedRace.addListener(trackedRaceReplicator);
@@ -1362,16 +1364,18 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
// (com.sap.sailing.server) can see
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
regattasByName.clear();
regattasByName.putAll((Map<String, Regatta>) ois.readObject());
regattasObservedForDefaultLeaderboard.clear();
regattaTrackingCache.clear();
leaderboardGroupsByName.clear();
leaderboardsByName.clear();
regattasByName.putAll((Map<String, Regatta>) ois.readObject());
// it is important that the leaderboards and tracked regattas are cleared before auto-linking to
// old leaderboards takes place which then don't match the new ones
for (DynamicTrackedRegatta trackedRegattaToObserve : (Set<DynamicTrackedRegatta>) ois.readObject()) {
ensureRegattaIsObservedForDefaultLeaderboardAndAutoLeaderboardLinking(trackedRegattaToObserve);
}
regattaTrackingCache.clear();
regattaTrackingCache.putAll((Map<Regatta, DynamicTrackedRegatta>) ois.readObject());
leaderboardGroupsByName.clear();
leaderboardGroupsByName.putAll((Map<String, LeaderboardGroup>) ois.readObject());
leaderboardsByName.clear();
leaderboardsByName.putAll((Map<String, Leaderboard>) ois.readObject());
logger.info("Done with initial replication on "+this);
} finally {