Search in sources :

Example 1 with KillSwitch

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

Aggregations

Done (akka.Done)1 NotUsed (akka.NotUsed)1 ActorSystem (akka.actor.ActorSystem)1 ExecutionContexts (akka.dispatch.ExecutionContexts)1 Pair (akka.japi.Pair)1 ActorMaterializer (akka.stream.ActorMaterializer)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 OplogOperation (com.eightkdata.mongowp.server.api.oplog.OplogOperation)1 Empty (com.eightkdata.mongowp.server.api.tools.Empty)1 Supplier (com.google.common.base.Supplier)1 Throwables (com.google.common.base.Throwables)1 BatchFlow (com.torodb.concurrent.akka.BatchFlow)1