use of akka.japi.Pair in project torodb by torodb.
the class DefaultOplogApplier method apply.
@Override
public ApplyingJob apply(OplogFetcher fetcher, ApplierContext applierContext) {
Materializer materializer = ActorMaterializer.create(actorSystem);
RunnableGraph<Pair<UniqueKillSwitch, CompletionStage<Done>>> graph = createOplogSource(fetcher).async().via(createBatcherFlow(applierContext)).viaMat(KillSwitches.single(), Keep.right()).async().map(analyzedElem -> {
for (AnalyzedOplogBatch analyzedOplogBatch : analyzedElem.analyzedBatch) {
batchExecutor.apply(analyzedOplogBatch, applierContext);
}
return analyzedElem;
}).map(this::metricExecution).toMat(Sink.foreach(this::storeLastAppliedOp), (killSwitch, completionStage) -> new Pair<>(killSwitch, completionStage));
Pair<UniqueKillSwitch, CompletionStage<Done>> pair = graph.run(materializer);
UniqueKillSwitch killSwitch = pair.first();
CompletableFuture<Empty> whenComplete = pair.second().toCompletableFuture().thenApply(done -> Empty.getInstance()).whenComplete((done, t) -> {
fetcher.close();
if (done != null) {
LOGGER.trace("Oplog replication stream finished normally");
} else {
Throwable cause;
if (t instanceof CompletionException) {
cause = t.getCause();
} else {
cause = t;
}
//the completable future has been cancelled
if (cause instanceof CancellationException) {
LOGGER.debug("Oplog replication stream has been cancelled");
killSwitch.shutdown();
} else {
//in this case the exception should came from the stream
cause = Throwables.getRootCause(cause);
LOGGER.error("Oplog replication stream finished exceptionally: " + cause.getLocalizedMessage(), cause);
//the stream should be finished exceptionally, but just in case we
//notify the kill switch to stop the stream.
killSwitch.shutdown();
}
}
});
return new DefaultApplyingJob(killSwitch, whenComplete);
}
use of akka.japi.Pair in project torodb by torodb.
the class AkkaDbCloner method cloneCollection.
private void cloneCollection(MongodServer localServer, MongoConnection remoteConnection, String toDb, CloneOptions opts, Materializer materializer, Entry collToClone) throws MongoException {
String collName = collToClone.getCollectionName();
MongoCursor<BsonDocument> cursor = openCursor(remoteConnection, collName, opts);
CollectionIterator iterator = new CollectionIterator(cursor, retrier);
Source<BsonDocument, NotUsed> source = Source.fromIterator(() -> iterator).buffer(cursorBatchBufferSize, OverflowStrategy.backpressure()).async();
Flow<BsonDocument, Pair<Integer, Integer>, NotUsed> inserterFlow;
if (maxParallelInsertTasks == 1) {
inserterFlow = createCloneDocsWorker(localServer, toDb, collName);
} else {
Graph<FlowShape<BsonDocument, Pair<Integer, Integer>>, NotUsed> graph = GraphDSL.create(builder -> {
UniformFanOutShape<BsonDocument, BsonDocument> balance = builder.add(Balance.create(maxParallelInsertTasks, false));
UniformFanInShape<Pair<Integer, Integer>, Pair<Integer, Integer>> merge = builder.add(Merge.create(maxParallelInsertTasks, false));
for (int i = 0; i < maxParallelInsertTasks; i++) {
builder.from(balance.out(i)).via(builder.add(createCloneDocsWorker(localServer, toDb, collName).async())).toInlet(merge.in(i));
}
return FlowShape.of(balance.in(), merge.out());
});
inserterFlow = Flow.fromGraph(graph);
}
try {
source.via(inserterFlow).fold(new Tuple3<>(0, 0, clock.instant()), (acum, batch) -> postInsertFold(toDb, collName, acum, batch)).toMat(Sink.foreach(tuple -> logCollectionCloning(toDb, collName, tuple.t1(), tuple.t2())), Keep.right()).run(materializer).toCompletableFuture().join();
} catch (CompletionException ex) {
Throwable cause = ex.getCause();
if (cause != null) {
throw new CloningException("Error while cloning " + toDb + "." + collName, cause);
}
throw ex;
}
}
Aggregations