use of com.torodb.mongodb.repl.oplogreplier.ApplierContext in project torodb by torodb.
the class SimpleAnalyzedOplogBatchExecutorTest method testVisit_SingleOp_OplogApplyingEx.
@Test
public void testVisit_SingleOp_OplogApplyingEx() throws Exception {
//GIVEN
OplogOperation operation = mock(OplogOperation.class);
SingleOpAnalyzedOplogBatch batch = new SingleOpAnalyzedOplogBatch(operation);
ApplierContext applierContext = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
Timer timer = mock(Timer.class);
Context context = mock(Context.class);
given(metrics.getSingleOpTimer(operation)).willReturn(timer);
given(timer.time()).willReturn(context);
doThrow(new OplogApplyingException(new MongoException(ErrorCode.BAD_VALUE))).when(executor).execute(operation, applierContext);
//WHEN
try {
executor.visit(batch, applierContext);
fail("An exception was expected");
} catch (RetrierGiveUpException | RetrierAbortException ignore) {
}
//THEN
then(metrics).should().getSingleOpTimer(operation);
then(timer).should().time();
then(executor).should(times(1)).execute(operation, applierContext);
}
use of com.torodb.mongodb.repl.oplogreplier.ApplierContext in project torodb by torodb.
the class RecoveryService method applyOplog.
/**
* Applies all the oplog operations stored on the remote server whose optime is higher than
* <em>from</em> but lower or equal than <em>to</em>.
*
* @param myOplog
* @param remoteOplog
* @param to
* @param from
*/
private void applyOplog(OplogReader remoteOplog, OpTime from, OpTime to) throws TryAgainException, MongoException, FatalErrorException {
MongoCursor<OplogOperation> oplogCursor = remoteOplog.between(from, true, to, true);
if (!oplogCursor.hasNext()) {
throw new OplogStartMissingException(remoteOplog.getSyncSource());
}
OplogOperation firstOp = oplogCursor.next();
if (!firstOp.getOpTime().equals(from)) {
throw new TryAgainException("Remote oplog does not cointain our last operation");
}
OplogFetcher fetcher = new LimitedOplogFetcher(oplogCursor);
ApplierContext context = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
try {
oplogApplier.apply(fetcher, context).waitUntilFinished();
} catch (StopReplicationException | RollbackReplicationException | CancellationException | UnexpectedOplogApplierException ex) {
throw new FatalErrorException(ex);
}
OpTime lastAppliedOptime;
try (ReadOplogTransaction oplogTrans = oplogManager.createReadTransaction()) {
lastAppliedOptime = oplogTrans.getLastAppliedOptime();
}
if (!lastAppliedOptime.equals(to)) {
LOGGER.warn("Unexpected optime for last operation to apply. " + "Expected " + to + ", but " + lastAppliedOptime + " found");
}
}
use of com.torodb.mongodb.repl.oplogreplier.ApplierContext in project torodb by torodb.
the class ConcurrentOplogBatchExecutorTest method testExecute.
@Test
public void testExecute() throws Exception {
int batchSize = 100;
int opsPerJob = 20;
int subBatchSize = 11;
int subBatchesPerJob = opsPerJob / subBatchSize + (opsPerJob % subBatchSize != 0 ? 1 : 0);
int expectedSize = batchSize * subBatchesPerJob;
//GIVEN
CudAnalyzedOplogBatch batch = mock(CudAnalyzedOplogBatch.class);
List<NamespaceJob> jobs = new ArrayList<>();
for (int i = 0; i < batchSize; i++) {
jobs.add(new NamespaceJob("db", "col", Lists.newArrayList(Stream.iterate(createAnalyzedOp(null), this::createAnalyzedOp).limit(opsPerJob).iterator())));
}
AtomicInteger callablesCounter = new AtomicInteger(0);
ApplierContext context = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
Histogram mockHistogram = mock(Histogram.class);
Meter mockMeter = mock(Meter.class);
given(batch.streamNamespaceJobs()).willReturn(jobs.stream());
given(subBatchHeuristic.getSubBatchSize(any())).willReturn(subBatchSize);
given(metrics.getSubBatchSizeHistogram()).willReturn(mockHistogram);
given(metrics.getSubBatchSizeMeter()).willReturn(mockMeter);
given(streamExecutor.execute(any())).willAnswer(new Answer<CompletableFuture<?>>() {
@Override
public CompletableFuture<?> answer(InvocationOnMock invocation) throws Throwable {
CompletableFuture<Object> completableFuture = new CompletableFuture<>();
completableFuture.complete(new Object());
Stream<Callable<?>> callables = invocation.getArgument(0);
callablesCounter.addAndGet((int) callables.count());
return completableFuture;
}
});
//WHEN
executor.execute(batch, context);
//THEN
then(mockHistogram).should().update(expectedSize);
then(mockMeter).should().mark(expectedSize);
assertEquals(expectedSize, callablesCounter.get());
}
use of com.torodb.mongodb.repl.oplogreplier.ApplierContext in project torodb by torodb.
the class SimpleAnalyzedOplogBatchExecutorTest method testExecute_NamespaceJob.
@Test
public void testExecute_NamespaceJob() throws Exception {
//GIVEN
ApplierContext applierContext = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
Context context = mock(Context.class);
NamespaceJob job = mock(NamespaceJob.class);
given(metrics.getNamespaceBatchTimer().time()).willReturn(context);
//WHEN
executor.execute(job, applierContext, conn);
//THEN
then(metrics).should(atLeastOnce()).getNamespaceBatchTimer();
then(metrics.getNamespaceBatchTimer()).should().time();
then(context).should().close();
//TODO: This might be changed once the backend throws UniqueIndexViolation
then(namespaceJobExecutor).should().apply(eq(job), eq(writeTrans), eq(applierContext), any(Boolean.class));
}
use of com.torodb.mongodb.repl.oplogreplier.ApplierContext in project torodb by torodb.
the class SimpleAnalyzedOplogBatchExecutorTest method testVisit_SingleOp_Success.
@Test
public void testVisit_SingleOp_Success() throws Exception {
//GIVEN
OplogOperation operation = mock(OplogOperation.class);
SingleOpAnalyzedOplogBatch batch = new SingleOpAnalyzedOplogBatch(operation);
ApplierContext applierContext = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
Timer timer = mock(Timer.class);
Context context = mock(Context.class);
given(metrics.getSingleOpTimer(operation)).willReturn(timer);
given(timer.time()).willReturn(context);
doNothing().when(executor).execute(any(OplogOperation.class), any());
//WHEN
OplogOperation result = executor.visit(batch, applierContext);
//THEN
then(metrics).should().getSingleOpTimer(operation);
then(timer).should().time();
then(context).should().close();
then(executor).should(times(1)).execute(operation, applierContext);
assertEquals(operation, result);
}
Aggregations