mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-06 02:52:22 +00:00
introduced queueing service for operations unsent to master
Change-Id: I0021082ec96b26b4302821a37acf2eb085baf2af
This commit is contained in:
1 parent
4543dd2089
commit
e633e66766
13 files changed
+266
-31
No files matched your search
+24
@@ -27,8 +27,11 @@ import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sse.replication.OperationExecutionListener;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.ReplicableWithObjectInputStream;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.ReplicationService;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
|
||||
/**
|
||||
* This is the main entry point of the {@link SensorFixStore} based fix tracking.
|
||||
@@ -51,6 +54,14 @@ public class RegattaLogFixTrackerRegattaListener extends AbstractTrackedRegattaA
|
||||
private final ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
|
||||
private final SensorFixMapperFactory sensorFixMapperFactory;
|
||||
|
||||
/**
|
||||
* This field is expected to be set by the {@link ReplicationService} once it has "adopted" this replicable.
|
||||
* The {@link ReplicationService} "injects" this service so it can be used here as a delegate for the
|
||||
* {@link UnsentOperationsToMasterSender#retrySendingLater(OperationWithResult, OperationsToMasterSender)}
|
||||
* method.
|
||||
*/
|
||||
private UnsentOperationsToMasterSender unsentOperationsToMasterSender;
|
||||
|
||||
public RegattaLogFixTrackerRegattaListener(
|
||||
ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker,
|
||||
SensorFixMapperFactory sensorFixMapperFactory) {
|
||||
@@ -215,4 +226,17 @@ public class RegattaLogFixTrackerRegattaListener extends AbstractTrackedRegattaA
|
||||
private boolean isReplica() {
|
||||
return master != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnsentOperationToMasterSender(UnsentOperationsToMasterSender service) {
|
||||
this.unsentOperationsToMasterSender = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(
|
||||
OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender) {
|
||||
if (unsentOperationsToMasterSender != null) {
|
||||
unsentOperationsToMasterSender.retrySendingLater(operationWithResult, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,10 @@ import com.sap.sse.datamining.shared.GroupKey;
|
||||
import com.sap.sse.replication.OperationExecutionListener;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.ReplicationService;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
import com.sap.sse.util.ClearStateTestSupport;
|
||||
|
||||
/**
|
||||
@@ -86,6 +89,14 @@ public class PolarDataServiceImpl implements ReplicablePolarService, ClearStateT
|
||||
|
||||
private DomainFactory domainFactory;
|
||||
|
||||
/**
|
||||
* This field is expected to be set by the {@link ReplicationService} once it has "adopted" this replicable.
|
||||
* The {@link ReplicationService} "injects" this service so it can be used here as a delegate for the
|
||||
* {@link UnsentOperationsToMasterSender#retrySendingLater(OperationWithResult, OperationsToMasterSender)}
|
||||
* method.
|
||||
*/
|
||||
private UnsentOperationsToMasterSender unsentOperationsToMasterSender;
|
||||
|
||||
/**
|
||||
* Constructs the polar data service with default generation settings.
|
||||
*/
|
||||
@@ -421,4 +432,17 @@ public class PolarDataServiceImpl implements ReplicablePolarService, ClearStateT
|
||||
public void clearState() throws Exception {
|
||||
resetState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnsentOperationToMasterSender(UnsentOperationsToMasterSender service) {
|
||||
this.unsentOperationsToMasterSender = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(
|
||||
OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender) {
|
||||
if (unsentOperationsToMasterSender != null) {
|
||||
unsentOperationsToMasterSender.retrySendingLater(operationWithResult, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.sap.sailing.server.replication.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.impl.UnsentOperationsSenderJob;
|
||||
|
||||
public class UnsentOperationSenderJobTest implements OperationsToMasterSender<RacingEventService, OperationWithResult<RacingEventService, String>> {
|
||||
private UnsentOperationsSenderJob job;
|
||||
private int resendCount;
|
||||
private CountDownLatch latch;
|
||||
|
||||
// @Rule public Timeout timeout = new Timeout(10, TimeUnit.SECONDS);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
job = new UnsentOperationsSenderJob();
|
||||
resendCount = 0;
|
||||
latch = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResendThatFailsAtLeastOnce() throws InterruptedException, BrokenBarrierException {
|
||||
final OperationWithResult<RacingEventService, String> operationWithResult = null;
|
||||
final OperationsToMasterSender<RacingEventService, OperationWithResult<RacingEventService, String>> sender = this;
|
||||
job.retrySendingLater(operationWithResult, sender);
|
||||
latch.await();
|
||||
assertEquals(2, resendCount);
|
||||
}
|
||||
|
||||
public <T> void sendReplicaInitiatedOperationToMaster(OperationWithResult<RacingEventService, T> operation) throws IOException {
|
||||
logger.info("resending at count "+resendCount);
|
||||
if (resendCount++ == 0) {
|
||||
throw new IOException("First resend failed");
|
||||
} else {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(
|
||||
OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender) {
|
||||
job.retrySendingLater(operationWithResult, sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getId() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReplicationMasterDescriptor getMasterDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOperation(OperationWithResult<?, ?> operation, OutputStream outputStream, boolean closeStream) throws IOException {}
|
||||
|
||||
@Override
|
||||
public void addOperationSentToMasterForReplication(OperationWithResultWithIdWrapper<RacingEventService, ?> operationWithResultWithIdWrapper) {}
|
||||
}
|
||||
+24
@@ -285,7 +285,10 @@ import com.sap.sse.pairinglist.PairingListTemplateFactory;
|
||||
import com.sap.sse.replication.OperationExecutionListener;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.ReplicationService;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
import com.sap.sse.shared.media.ImageDescriptor;
|
||||
import com.sap.sse.shared.media.VideoDescriptor;
|
||||
import com.sap.sse.util.ClearStateTestSupport;
|
||||
@@ -510,6 +513,14 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
|
||||
private final PairingListTemplateFactory pairingListTemplateFactory = PairingListTemplateFactory.INSTANCE;
|
||||
|
||||
/**
|
||||
* This field is expected to be set by the {@link ReplicationService} once it has "adopted" this replicable.
|
||||
* The {@link ReplicationService} "injects" this service so it can be used here as a delegate for the
|
||||
* {@link UnsentOperationsToMasterSender#retrySendingLater(OperationWithResult, OperationsToMasterSender)}
|
||||
* method.
|
||||
*/
|
||||
private UnsentOperationsToMasterSender unsentOperationsToMasterSender;
|
||||
|
||||
/**
|
||||
* Providing the constructor parameters for a new {@link RacingEventServiceImpl} instance is a bit tricky
|
||||
* in some cases because containment and initialization order of some types is fairly tightly coupled.
|
||||
@@ -4352,4 +4363,17 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
competitorDescriptor.getTimeOnDistanceAllowancePerNauticalMile(), searchTag, boat);
|
||||
return competitorWithBoat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnsentOperationToMasterSender(UnsentOperationsToMasterSender service) {
|
||||
this.unsentOperationsToMasterSender = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(
|
||||
OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender) {
|
||||
if (unsentOperationsToMasterSender != null) {
|
||||
unsentOperationsToMasterSender.retrySendingLater(operationWithResult, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -26,7 +26,10 @@ import com.sap.sse.filestorage.FileStorageServiceResolver;
|
||||
import com.sap.sse.replication.OperationExecutionListener;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.ReplicationService;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
|
||||
/**
|
||||
* Implements {@link ServiceTrackerCustomizer} so that all {@link FileStorageServices} announced in the registry can
|
||||
@@ -55,6 +58,14 @@ public class FileStorageManagementServiceImpl implements ReplicableFileStorageMa
|
||||
private FileStorageServicePropertyStore propertyStore;
|
||||
private final FileStorageServiceResolver serviceResolver;
|
||||
|
||||
/**
|
||||
* This field is expected to be set by the {@link ReplicationService} once it has "adopted" this replicable.
|
||||
* The {@link ReplicationService} "injects" this service so it can be used here as a delegate for the
|
||||
* {@link UnsentOperationsToMasterSender#retrySendingLater(OperationWithResult, OperationsToMasterSender)}
|
||||
* method.
|
||||
*/
|
||||
private UnsentOperationsToMasterSender unsentOperationForMasterQueue;
|
||||
|
||||
public FileStorageManagementServiceImpl(TypeBasedServiceFinder<FileStorageService> serviceFinder,
|
||||
FileStorageServicePropertyStore propertyStore) {
|
||||
this.serviceFinder = serviceFinder;
|
||||
@@ -235,4 +246,17 @@ public class FileStorageManagementServiceImpl implements ReplicableFileStorageMa
|
||||
public void setCurrentlyApplyingOperationReceivedFromMaster(boolean currentlyApplyingOperationReceivedFromMaster) {
|
||||
this.currentlyApplyingOperationReceivedFromMaster.set(currentlyApplyingOperationReceivedFromMaster);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnsentOperationToMasterSender(UnsentOperationsToMasterSender service) {
|
||||
this.unsentOperationForMasterQueue = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(
|
||||
OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender) {
|
||||
if (unsentOperationForMasterQueue != null) {
|
||||
unsentOperationForMasterQueue.retrySendingLater(operationWithResult, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,9 @@ import com.sap.sse.mail.SerializableMultipartSupplier;
|
||||
import com.sap.sse.replication.OperationExecutionListener;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
import com.sap.sse.util.ObjectInputStreamResolvingAgainstCache;
|
||||
|
||||
public class MailServiceImpl implements ReplicableMailService {
|
||||
@@ -51,6 +53,14 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
private ThreadLocal<Boolean> currentlyApplyingOperationReceivedFromMaster = ThreadLocal.withInitial(() -> false);
|
||||
|
||||
private final MailServiceResolver mailServiceResolver;
|
||||
|
||||
/**
|
||||
* This field is expected to be set by the {@link ReplicationService} once it has "adopted" this replicable.
|
||||
* The {@link ReplicationService} "injects" this service so it can be used here as a delegate for the
|
||||
* {@link UnsentOperationsToMasterSender#retrySendingLater(OperationWithResult, OperationsToMasterSender)}
|
||||
* method.
|
||||
*/
|
||||
private UnsentOperationsToMasterSender unsentOperationForMasterQueue;
|
||||
|
||||
public MailServiceImpl(Properties mailProperties, MailServiceResolver mailServiceResolver) {
|
||||
this.mailProperties = mailProperties;
|
||||
@@ -244,4 +254,17 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
public void setCurrentlyApplyingOperationReceivedFromMaster(boolean currentlyApplyingOperationReceivedFromMaster) {
|
||||
this.currentlyApplyingOperationReceivedFromMaster.set(currentlyApplyingOperationReceivedFromMaster);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnsentOperationToMasterSender(UnsentOperationsToMasterSender service) {
|
||||
this.unsentOperationForMasterQueue = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(
|
||||
OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender) {
|
||||
if (unsentOperationForMasterQueue != null) {
|
||||
unsentOperationForMasterQueue.retrySendingLater(operationWithResult, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-1
@@ -7,10 +7,30 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.util.HttpUrlConnectionHelper;
|
||||
|
||||
public interface OperationsToMasterSender<S, O extends OperationWithResult<S, ?>> extends Replicable<S, O>, UnsentOperationsForMasterQueue {
|
||||
public interface OperationsToMasterSender<S, O extends OperationWithResult<S, ?>> extends UnsentOperationsToMasterSender, WithID {
|
||||
final Logger logger = Logger.getLogger(OperationsToMasterSender.class.getName());
|
||||
|
||||
/**
|
||||
* @return the descriptor of the master from which this replica is replicating this {@link Replicable}, or
|
||||
* {@code null} if this {@link Replicable} is currently running as a master.
|
||||
*/
|
||||
ReplicationMasterDescriptor getMasterDescriptor();
|
||||
|
||||
/**
|
||||
* Writes an operation to an output stream such that it can be read by {@link #readOperation}.
|
||||
*
|
||||
* @param closeStream
|
||||
* if <code>true</code>, the stream will be closed after having written the operation; in any case, the
|
||||
* content written will be flushed to the <code>outputStream</code> so that the caller may continue to
|
||||
* invoke this method for other operations and/or on other replicables without producing corrupt data.
|
||||
*/
|
||||
void writeOperation(OperationWithResult<?, ?> operation, OutputStream outputStream, boolean closeStream) throws IOException;
|
||||
|
||||
/**
|
||||
* When a replica has initiated (not received through replication) an operation, this operation needs to be sent to
|
||||
* the master for execution from where it will replicate across the replication tree. This method uses the
|
||||
|
||||
+10
-19
@@ -8,8 +8,6 @@ import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.operationaltransformation.Operation;
|
||||
import com.sap.sse.operationaltransformation.OperationWithTransformationSupport;
|
||||
import com.sap.sse.util.ObjectInputStreamResolvingAgainstCache;
|
||||
@@ -57,7 +55,8 @@ import com.sap.sse.util.ThreadLocalTransporter;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface Replicable<S, O extends OperationWithResult<S, ?>> extends Replicator<S, O>, WithID {
|
||||
public interface Replicable<S, O extends OperationWithResult<S, ?>>
|
||||
extends OperationsToMasterSender<S, OperationWithResult<S, ?>>, Replicator<S, O> {
|
||||
static final Logger logger = Logger.getLogger(Replicable.class.getName());
|
||||
|
||||
/**
|
||||
@@ -102,12 +101,6 @@ public interface Replicable<S, O extends OperationWithResult<S, ?>> extends Repl
|
||||
|
||||
void stoppedReplicatingFrom(ReplicationMasterDescriptor master);
|
||||
|
||||
/**
|
||||
* @return the descriptor of the master from which this replica is replicating this {@link Replicable}, or
|
||||
* {@code null} if this {@link Replicable} is currently running as a master.
|
||||
*/
|
||||
ReplicationMasterDescriptor getMasterDescriptor();
|
||||
|
||||
/**
|
||||
* An operation execution listener must be able to process notifications of operations being executed that have
|
||||
* type <code>S</code> or any more specific type. The listener can achieve this also by accepting any type more general than
|
||||
@@ -160,16 +153,6 @@ public interface Replicable<S, O extends OperationWithResult<S, ?>> extends Repl
|
||||
*/
|
||||
O readOperation(InputStream inputStream) throws IOException, ClassNotFoundException;
|
||||
|
||||
/**
|
||||
* Writes an operation to an output stream such that it can be read by {@link #readOperation}.
|
||||
*
|
||||
* @param closeStream
|
||||
* if <code>true</code>, the stream will be closed after having written the operation; in any case, the
|
||||
* content written will be flushed to the <code>outputStream</code> so that the caller may continue to
|
||||
* invoke this method for other operations and/or on other replicables without producing corrupt data.
|
||||
*/
|
||||
void writeOperation(OperationWithResult<?, ?> operation, OutputStream outputStream, boolean closeStream) throws IOException;
|
||||
|
||||
/**
|
||||
* Checks if {@link #hasSentOperationToMaster(OperationWithResultWithIdWrapper) the operation was previously
|
||||
* sent to the master}. If so, the operation is ignored because it has been applied before to this replica.
|
||||
@@ -265,4 +248,12 @@ public interface Replicable<S, O extends OperationWithResult<S, ?>> extends Repl
|
||||
*/
|
||||
boolean hasSentOperationToMaster(OperationWithResult<S, ?> operation);
|
||||
|
||||
|
||||
/**
|
||||
* Injects a service into this replicable that this instance of {@link UnsentOperationsToMasterSender} can use
|
||||
* as a delegate to implement the {@link UnsentOperationsToMasterSender#retrySendingLater(OperationWithResult, OperationsToMasterSender)}
|
||||
* method. This replicable may not be able to enqueue operations for re-trying sending to master after
|
||||
* an error occurred unless this method has been used to announce the service.
|
||||
*/
|
||||
void setUnsentOperationToMasterSender(UnsentOperationsToMasterSender service);
|
||||
}
|
||||
+6
-2
@@ -13,7 +13,7 @@ import java.util.logging.Logger;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.operationaltransformation.Operation;
|
||||
|
||||
public interface ReplicableWithObjectInputStream<S, O extends OperationWithResult<S, ?>> extends OperationsToMasterSender<S, O> {
|
||||
public interface ReplicableWithObjectInputStream<S, O extends OperationWithResult<S, ?>> extends Replicable<S, O> {
|
||||
static final Logger logger = Logger.getLogger(ReplicableWithObjectInputStream.class.getName());
|
||||
|
||||
/**
|
||||
@@ -123,7 +123,11 @@ public interface ReplicableWithObjectInputStream<S, O extends OperationWithResul
|
||||
try {
|
||||
sendReplicaInitiatedOperationToMaster(castOperation);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, "Exception trying to send operation "+operation+" to master for replication", e);
|
||||
logger.log(Level.INFO, "Error sending operation "+operation+" to master "+getMasterDescriptor()+
|
||||
". Queueing for later delivery.");
|
||||
// remove the operation that failed to arrive on the master server from those marked as sent to master for now:
|
||||
hasSentOperationToMaster(operation);
|
||||
retrySendingLater(castOperation, this);
|
||||
}
|
||||
}
|
||||
replicateReplicated(operation); // this anticipates receiving the operation back from master; then, the operation will be ignored;
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ package com.sap.sse.replication;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface UnsentOperationsForMasterQueue {
|
||||
public interface UnsentOperationsToMasterSender {
|
||||
/**
|
||||
* When this replica was unable to send an operation to the master, e.g., for connectivity issues or the
|
||||
* master currently not being available, passing the operation to this method will enqueue the operation
|
||||
@@ -16,5 +16,5 @@ public interface UnsentOperationsForMasterQueue {
|
||||
*
|
||||
* @param sender the object to use to try to send the operation to the master server upon the next attempt
|
||||
*/
|
||||
<S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(OperationWithResult<S, T> operationWithResultWithIdWrapper, OperationsToMasterSender<S, O> sender);
|
||||
<S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender);
|
||||
}
|
||||
+7
-5
@@ -43,7 +43,7 @@ import com.sap.sse.replication.ReplicablesProvider.ReplicableLifeCycleListener;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.ReplicationReceiver;
|
||||
import com.sap.sse.replication.ReplicationService;
|
||||
import com.sap.sse.replication.UnsentOperationsForMasterQueue;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
import com.sap.sse.util.HttpUrlConnectionHelper;
|
||||
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
@@ -76,7 +76,7 @@ import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
* @author Frank Mittag, Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class ReplicationServiceImpl implements ReplicationService, UnsentOperationsForMasterQueue {
|
||||
public class ReplicationServiceImpl implements ReplicationService, UnsentOperationsToMasterSender {
|
||||
private static final Logger logger = Logger.getLogger(ReplicationServiceImpl.class.getName());
|
||||
|
||||
private final ReplicationInstancesManager replicationInstancesManager;
|
||||
@@ -261,7 +261,7 @@ public class ReplicationServiceImpl implements ReplicationService, UnsentOperati
|
||||
synchronized (replicationInstancesManager) {
|
||||
// .. and at least one of them wants to replicate the replicable with that ID
|
||||
if (Util.contains(replicationInstancesManager.getAllReplicableIdsAtLeastOneReplicaIsReplicating(), replicable.getId().toString())) {
|
||||
ensureOperationExecutionListener(replicable);
|
||||
ensureOperationExecutionListenerAndInjectResetToMasterService(replicable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -383,7 +383,7 @@ public class ReplicationServiceImpl implements ReplicationService, UnsentOperati
|
||||
private void addAsListenerToReplicables(String[] replicableIdsAsStringForReplicablesToReplicate) {
|
||||
for (final String replicableIdAsStringForReplicableToReplicate : replicableIdsAsStringForReplicablesToReplicate) {
|
||||
Replicable<?, ?> replicable = getReplicable(replicableIdAsStringForReplicableToReplicate, /* wait */ true);
|
||||
ensureOperationExecutionListener(replicable);
|
||||
ensureOperationExecutionListenerAndInjectResetToMasterService(replicable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,11 +392,13 @@ public class ReplicationServiceImpl implements ReplicationService, UnsentOperati
|
||||
* {@code replicable} and remembered in {@link #executionListenersByReplicableIdAsString}. Otherwise, this method is
|
||||
* a no-op.
|
||||
*/
|
||||
private <S> void ensureOperationExecutionListener(Replicable<S, ?> replicable) {
|
||||
private <S> void ensureOperationExecutionListenerAndInjectResetToMasterService(Replicable<S, ?> replicable) {
|
||||
if (!executionListenersByReplicableIdAsString.containsKey(replicable.getId().toString())) {
|
||||
final ReplicationServiceExecutionListener<S> listener = new ReplicationServiceExecutionListener<S>(this, replicable);
|
||||
executionListenersByReplicableIdAsString.put(replicable.getId().toString(), listener);
|
||||
}
|
||||
// the following is idempotent and needs no roll-back
|
||||
replicable.setUnsentOperationToMasterSender(unsentOperationsSenderJob);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-2
@@ -11,7 +11,7 @@ import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.UnsentOperationsForMasterQueue;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
import com.sap.sse.util.ThreadPoolUtil;
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@ import com.sap.sse.util.ThreadPoolUtil;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class UnsentOperationsSenderJob implements UnsentOperationsForMasterQueue, Runnable {
|
||||
public class UnsentOperationsSenderJob implements UnsentOperationsToMasterSender, Runnable {
|
||||
private static final Logger logger = Logger.getLogger(UnsentOperationsSenderJob.class.getName());
|
||||
private final static Duration MAX_WAIT_TIME_BETWEEN_ATTEMPTS = Duration.ONE_MINUTE;
|
||||
|
||||
@@ -65,6 +65,7 @@ public class UnsentOperationsSenderJob implements UnsentOperationsForMasterQueue
|
||||
*/
|
||||
private synchronized void ensureScheduled() {
|
||||
if (!scheduled) {
|
||||
logger.info("Scheduling replication operation re-send to master in "+nextWaitDuration);
|
||||
ThreadPoolUtil.INSTANCE.getDefaultBackgroundTaskThreadPoolExecutor().schedule(this,
|
||||
/* delay */ nextWaitDuration.asMillis(), TimeUnit.MILLISECONDS);
|
||||
scheduled = true;
|
||||
|
||||
@@ -72,7 +72,10 @@ import com.sap.sse.mail.MailService;
|
||||
import com.sap.sse.replication.OperationExecutionListener;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.replication.OperationsToMasterSender;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.ReplicationService;
|
||||
import com.sap.sse.replication.UnsentOperationsToMasterSender;
|
||||
import com.sap.sse.security.BearerAuthenticationToken;
|
||||
import com.sap.sse.security.ClientUtils;
|
||||
import com.sap.sse.security.Credential;
|
||||
@@ -121,6 +124,14 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
private ThreadLocal<Boolean> currentlyFillingFromInitialLoad = ThreadLocal.withInitial(() -> false);
|
||||
|
||||
private ThreadLocal<Boolean> currentlyApplyingOperationReceivedFromMaster = ThreadLocal.withInitial(() -> false);
|
||||
|
||||
/**
|
||||
* This field is expected to be set by the {@link ReplicationService} once it has "adopted" this replicable.
|
||||
* The {@link ReplicationService} "injects" this service so it can be used here as a delegate for the
|
||||
* {@link UnsentOperationsToMasterSender#retrySendingLater(OperationWithResult, OperationsToMasterSender)}
|
||||
* method.
|
||||
*/
|
||||
private UnsentOperationsToMasterSender unsentOperationsToMasterSender;
|
||||
|
||||
private static Ini shiroConfiguration;
|
||||
static {
|
||||
@@ -1147,4 +1158,17 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
public void removeAllSessions(String cacheName) {
|
||||
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory().removeAllSessions(cacheName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnsentOperationToMasterSender(UnsentOperationsToMasterSender service) {
|
||||
this.unsentOperationsToMasterSender = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, O extends OperationWithResult<S, ?>, T> void retrySendingLater(
|
||||
OperationWithResult<S, T> operationWithResult, OperationsToMasterSender<S, O> sender) {
|
||||
if (unsentOperationsToMasterSender != null) {
|
||||
unsentOperationsToMasterSender.retrySendingLater(operationWithResult, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user