Search in sources :

Example 1 with Materializer

use of akka.stream.Materializer 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 Materializer

use of akka.stream.Materializer in project torodb by torodb.

the class AkkaDbCloner method cloneDatabase.

@Override
public void cloneDatabase(String dstDb, MongoClient remoteClient, MongodServer localServer, CloneOptions opts) throws CloningException, NotMasterException, MongoException {
    Preconditions.checkState(isRunning(), "This db cloner is not running");
    if (!remoteClient.isRemote() && opts.getDbToClone().equals(dstDb)) {
        LOGGER.warn("Trying to clone a database to itself! Ignoring it");
        return;
    }
    String fromDb = opts.getDbToClone();
    CursorResult<Entry> listCollections;
    try (MongoConnection remoteConnection = remoteClient.openConnection()) {
        listCollections = ListCollectionsRequester.getListCollections(remoteConnection, fromDb, null);
    } catch (MongoException ex) {
        throw new CloningException("It was impossible to get information from the remote server", ex);
    }
    if (!opts.getWritePermissionSupplier().get()) {
        throw new NotMasterException("Destiny database cannot be written");
    }
    List<Entry> collsToClone = getCollsToClone(listCollections, fromDb, opts);
    if (!opts.getWritePermissionSupplier().get()) {
        throw new NotMasterException("Destiny database cannot be written " + "after get collections info");
    }
    try {
        for (Entry entry : collsToClone) {
            prepareCollection(localServer, dstDb, entry);
        }
    } catch (RollbackException ex) {
        throw new AssertionError("Unexpected rollback exception", ex);
    }
    Materializer materializer = ActorMaterializer.create(getActorSystem());
    try (MongoConnection remoteConnection = remoteClient.openConnection()) {
        if (opts.isCloneData()) {
            for (Entry entry : collsToClone) {
                LOGGER.info("Cloning collection data {}.{} into {}.{}", fromDb, entry.getCollectionName(), dstDb, entry.getCollectionName());
                try {
                    cloneCollection(localServer, remoteConnection, dstDb, opts, materializer, entry);
                } catch (CompletionException completionException) {
                    Throwable cause = completionException.getCause();
                    if (cause instanceof RollbackException) {
                        throw (RollbackException) cause;
                    }
                    throw completionException;
                }
            }
        }
        if (opts.isCloneIndexes()) {
            for (Entry entry : collsToClone) {
                LOGGER.info("Cloning collection indexes {}.{} into {}.{}", fromDb, entry.getCollectionName(), dstDb, entry.getCollectionName());
                try {
                    cloneIndex(localServer, dstDb, dstDb, remoteConnection, opts, entry.getCollectionName(), entry.getCollectionName());
                } catch (CompletionException completionException) {
                    Throwable cause = completionException.getCause();
                    if (cause instanceof RollbackException) {
                        throw (RollbackException) cause;
                    }
                    throw completionException;
                }
            }
        }
    }
}
Also used : MongoException(com.eightkdata.mongowp.exceptions.MongoException) RollbackException(com.torodb.core.transaction.RollbackException) Entry(com.torodb.mongodb.commands.signatures.admin.ListCollectionsCommand.ListCollectionsResult.Entry) CompletionException(java.util.concurrent.CompletionException) NotMasterException(com.eightkdata.mongowp.exceptions.NotMasterException) MongoConnection(com.eightkdata.mongowp.client.core.MongoConnection) ActorMaterializer(akka.stream.ActorMaterializer) Materializer(akka.stream.Materializer)

Aggregations

ActorMaterializer (akka.stream.ActorMaterializer)2 Materializer (akka.stream.Materializer)2 CompletionException (java.util.concurrent.CompletionException)2 Done (akka.Done)1 NotUsed (akka.NotUsed)1 ActorSystem (akka.actor.ActorSystem)1 ExecutionContexts (akka.dispatch.ExecutionContexts)1 Pair (akka.japi.Pair)1 KillSwitch (akka.stream.KillSwitch)1 KillSwitches (akka.stream.KillSwitches)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 MongoConnection (com.eightkdata.mongowp.client.core.MongoConnection)1 MongoException (com.eightkdata.mongowp.exceptions.MongoException)1 NotMasterException (com.eightkdata.mongowp.exceptions.NotMasterException)1 OplogOperation (com.eightkdata.mongowp.server.api.oplog.OplogOperation)1