Search in sources :

Example 1 with Pair

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);
}
Also used : AnalyzedOplogBatch(com.torodb.mongodb.repl.oplogreplier.batch.AnalyzedOplogBatch) BatchAnalyzerFactory(com.torodb.mongodb.repl.oplogreplier.batch.BatchAnalyzer.BatchAnalyzerFactory) BiFunction(java.util.function.BiFunction) Flow(akka.stream.javadsl.Flow) Source(akka.stream.javadsl.Source) Supplier(com.google.common.base.Supplier) KillSwitch(akka.stream.KillSwitch) Materializer(akka.stream.Materializer) CompletableFuture(java.util.concurrent.CompletableFuture) UniqueKillSwitch(akka.stream.UniqueKillSwitch) OplogManager(com.torodb.mongodb.repl.OplogManager) BatchAnalyzer(com.torodb.mongodb.repl.oplogreplier.batch.BatchAnalyzer) Inject(javax.inject.Inject) ActorMaterializer(akka.stream.ActorMaterializer) Keep(akka.stream.javadsl.Keep) RunnableGraph(akka.stream.javadsl.RunnableGraph) OplogOperation(com.eightkdata.mongowp.server.api.oplog.OplogOperation) Empty(com.eightkdata.mongowp.server.api.tools.Empty) OplogManagerPersistException(com.torodb.mongodb.repl.OplogManager.OplogManagerPersistException) AnalyzedOplogBatchExecutor(com.torodb.mongodb.repl.oplogreplier.batch.AnalyzedOplogBatchExecutor) ConcurrentToolsFactory(com.torodb.core.concurrent.ConcurrentToolsFactory) AnalyzedOplogBatch(com.torodb.mongodb.repl.oplogreplier.batch.AnalyzedOplogBatch) OplogFetcher(com.torodb.mongodb.repl.oplogreplier.fetcher.OplogFetcher) Shutdowner(com.torodb.core.Shutdowner) Done(akka.Done) CancellationException(java.util.concurrent.CancellationException) FiniteDuration(scala.concurrent.duration.FiniteDuration) Predicate(java.util.function.Predicate) ToIntFunction(java.util.function.ToIntFunction) Sink(akka.stream.javadsl.Sink) Throwables(com.google.common.base.Throwables) CompletionException(java.util.concurrent.CompletionException) KillSwitches(akka.stream.KillSwitches) WriteOplogTransaction(com.torodb.mongodb.repl.OplogManager.WriteOplogTransaction) ExecutionContexts(akka.dispatch.ExecutionContexts) Pair(akka.japi.Pair) TimeUnit(java.util.concurrent.TimeUnit) Duration(scala.concurrent.duration.Duration) List(java.util.List) Logger(org.apache.logging.log4j.Logger) CompletionStage(java.util.concurrent.CompletionStage) NotUsed(akka.NotUsed) BatchFlow(com.torodb.concurrent.akka.BatchFlow) ActorSystem(akka.actor.ActorSystem) Optional(java.util.Optional) LogManager(org.apache.logging.log4j.LogManager) Await(scala.concurrent.Await) Done(akka.Done) UniqueKillSwitch(akka.stream.UniqueKillSwitch) Empty(com.eightkdata.mongowp.server.api.tools.Empty) CancellationException(java.util.concurrent.CancellationException) CompletionException(java.util.concurrent.CompletionException) Materializer(akka.stream.Materializer) ActorMaterializer(akka.stream.ActorMaterializer) CompletionStage(java.util.concurrent.CompletionStage) Pair(akka.japi.Pair)

Example 2 with Pair

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;
    }
}
Also used : NotUsed(akka.NotUsed) Hint(com.torodb.core.retrier.Retrier.Hint) FlowShape(akka.stream.FlowShape) BsonDocument(com.eightkdata.mongowp.bson.BsonDocument) CompletionException(java.util.concurrent.CompletionException) Pair(akka.japi.Pair)

Aggregations

NotUsed (akka.NotUsed)2 Pair (akka.japi.Pair)2 CompletionException (java.util.concurrent.CompletionException)2 Done (akka.Done)1 ActorSystem (akka.actor.ActorSystem)1 ExecutionContexts (akka.dispatch.ExecutionContexts)1 ActorMaterializer (akka.stream.ActorMaterializer)1 FlowShape (akka.stream.FlowShape)1 KillSwitch (akka.stream.KillSwitch)1 KillSwitches (akka.stream.KillSwitches)1 Materializer (akka.stream.Materializer)1 UniqueKillSwitch (akka.stream.UniqueKillSwitch)1 Flow (akka.stream.javadsl.Flow)1 Keep (akka.stream.javadsl.Keep)1 RunnableGraph (akka.stream.javadsl.RunnableGraph)1 Sink (akka.stream.javadsl.Sink)1 Source (akka.stream.javadsl.Source)1 BsonDocument (com.eightkdata.mongowp.bson.BsonDocument)1 OplogOperation (com.eightkdata.mongowp.server.api.oplog.OplogOperation)1 Empty (com.eightkdata.mongowp.server.api.tools.Empty)1