Search in sources :

Example 1 with ExclusiveWriteMongodTransaction

use of com.torodb.mongodb.core.ExclusiveWriteMongodTransaction in project torodb by torodb.

the class TorodbSafeRequestProcessor method execute.

@Override
public <A, R> Status<R> execute(Request req, Command<? super A, ? super R> command, A arg, MongodConnection connection) {
    mongodMetrics.getCommands().mark();
    Timer timer = mongodMetrics.getTimer(command);
    try (Timer.Context ctx = timer.time()) {
        Callable<Status<R>> callable;
        RequiredTransaction commandType = commandsLibrary.getCommandType(command);
        switch(commandType) {
            case NO_TRANSACTION:
                callable = () -> {
                    return connection.getCommandsExecutor().execute(req, command, arg, connection);
                };
                break;
            case READ_TRANSACTION:
                callable = () -> {
                    try (ReadOnlyMongodTransaction trans = connection.openReadOnlyTransaction()) {
                        return trans.execute(req, command, arg);
                    }
                };
                break;
            case WRITE_TRANSACTION:
                callable = () -> {
                    try (WriteMongodTransaction trans = connection.openWriteTransaction(true)) {
                        Status<R> result = trans.execute(req, command, arg);
                        if (result.isOk()) {
                            trans.commit();
                        }
                        return result;
                    }
                };
                break;
            case EXCLUSIVE_WRITE_TRANSACTION:
                callable = () -> {
                    try (ExclusiveWriteMongodTransaction trans = connection.openExclusiveWriteTransaction(true)) {
                        Status<R> result = trans.execute(req, command, arg);
                        if (result.isOk()) {
                            trans.commit();
                        }
                        return result;
                    }
                };
                break;
            default:
                throw new AssertionError("Unexpected command type" + commandType);
        }
        try {
            return retrier.retry(callable);
        } catch (RetrierGiveUpException ex) {
            return Status.from(ErrorCode.CONFLICTING_OPERATION_IN_PROGRESS, "It was impossible to execute " + command.getCommandName() + " after several attempts");
        }
    }
}
Also used : Status(com.eightkdata.mongowp.Status) ExclusiveWriteMongodTransaction(com.torodb.mongodb.core.ExclusiveWriteMongodTransaction) WriteMongodTransaction(com.torodb.mongodb.core.WriteMongodTransaction) Timer(com.codahale.metrics.Timer) RequiredTransaction(com.torodb.mongodb.commands.TorodbCommandsLibrary.RequiredTransaction) ReadOnlyMongodTransaction(com.torodb.mongodb.core.ReadOnlyMongodTransaction) ExclusiveWriteMongodTransaction(com.torodb.mongodb.core.ExclusiveWriteMongodTransaction) RetrierGiveUpException(com.torodb.core.retrier.RetrierGiveUpException)

Example 2 with ExclusiveWriteMongodTransaction

use of com.torodb.mongodb.core.ExclusiveWriteMongodTransaction in project torodb by torodb.

the class SimpleAnalyzedOplogBatchExecutor method execute.

@Override
public void execute(OplogOperation op, ApplierContext context) throws OplogApplyingException, RollbackException, UserException {
    try (MongodConnection connection = server.openConnection();
        ExclusiveWriteMongodTransaction mongoTransaction = connection.openExclusiveWriteTransaction()) {
        oplogOperationApplier.apply(op, mongoTransaction, context);
        mongoTransaction.commit();
    }
}
Also used : MongodConnection(com.torodb.mongodb.core.MongodConnection) ExclusiveWriteMongodTransaction(com.torodb.mongodb.core.ExclusiveWriteMongodTransaction)

Example 3 with ExclusiveWriteMongodTransaction

use of com.torodb.mongodb.core.ExclusiveWriteMongodTransaction in project torodb by torodb.

the class ReplSyncApplier method runProtected.

@Override
protected void runProtected() {
    runThread = Thread.currentThread();
    /*
     * TODO: In general, the replication context can be set as not reaplying. But it is not frequent
     * but possible to stop the replication after some oplog ops have been apply but not marked as
     * executed on the oplog manager. For that reason, all oplog ops betwen the last operation that
     * have been marked as applyed and the current last operation on the remote oplog must be
     * executed as replying operations. As it is not possible to do that yet, we have to always
     * apply operations as replying to be safe.
     */
    ApplierContext applierContext = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
    while (isRunning()) {
        OplogOperation lastOperation = null;
        ExclusiveWriteMongodTransaction trans = connection.openExclusiveWriteTransaction();
        try (ExclusiveWriteMongodTransaction transaction = trans) {
            try {
                for (OplogOperation opToApply : callback.takeOps()) {
                    lastOperation = opToApply;
                    LOGGER.trace("Executing {}", opToApply);
                    try {
                        boolean done = false;
                        while (!done) {
                            try {
                                oplogOpApplier.apply(opToApply, transaction, applierContext);
                                transaction.commit();
                                done = true;
                            } catch (RollbackException ex) {
                                LOGGER.debug("Recived a rollback exception while applying an oplog op", ex);
                            }
                        }
                    } catch (OplogApplyingException ex) {
                        if (!callback.failedToApply(opToApply, ex)) {
                            LOGGER.error(serviceName() + " stopped because one operation " + "cannot be executed", ex);
                            break;
                        }
                    } catch (UserException ex) {
                        if (callback.failedToApply(opToApply, ex)) {
                            LOGGER.error(serviceName() + " stopped because one operation " + "cannot be executed", ex);
                            break;
                        }
                    } catch (Throwable ex) {
                        if (callback.failedToApply(opToApply, ex)) {
                            LOGGER.error(serviceName() + " stopped because " + "an unknown error", ex);
                            break;
                        }
                    }
                    callback.markAsApplied(opToApply);
                }
            } catch (InterruptedException ex) {
                LOGGER.debug("Interrupted applier thread while applying an operator");
            }
        }
        if (lastOperation != null) {
            try (WriteOplogTransaction oplogTransaction = oplogManager.createWriteTransaction()) {
                oplogTransaction.addOperation(lastOperation);
            } catch (OplogManagerPersistException ex) {
                if (callback.failedToApply(lastOperation, ex)) {
                    LOGGER.error(serviceName() + " stopped because " + "the last applied operation couldn't " + "be persisted", ex);
                    break;
                }
            }
        }
    }
}
Also used : OplogApplyingException(com.torodb.mongodb.repl.oplogreplier.OplogOperationApplier.OplogApplyingException) OplogManagerPersistException(com.torodb.mongodb.repl.OplogManager.OplogManagerPersistException) ExclusiveWriteMongodTransaction(com.torodb.mongodb.core.ExclusiveWriteMongodTransaction) UserException(com.torodb.core.exceptions.user.UserException) OplogOperation(com.eightkdata.mongowp.server.api.oplog.OplogOperation) RollbackException(com.torodb.core.transaction.RollbackException) WriteOplogTransaction(com.torodb.mongodb.repl.OplogManager.WriteOplogTransaction)

Aggregations

ExclusiveWriteMongodTransaction (com.torodb.mongodb.core.ExclusiveWriteMongodTransaction)3 Timer (com.codahale.metrics.Timer)1 Status (com.eightkdata.mongowp.Status)1 OplogOperation (com.eightkdata.mongowp.server.api.oplog.OplogOperation)1 UserException (com.torodb.core.exceptions.user.UserException)1 RetrierGiveUpException (com.torodb.core.retrier.RetrierGiveUpException)1 RollbackException (com.torodb.core.transaction.RollbackException)1 RequiredTransaction (com.torodb.mongodb.commands.TorodbCommandsLibrary.RequiredTransaction)1 MongodConnection (com.torodb.mongodb.core.MongodConnection)1 ReadOnlyMongodTransaction (com.torodb.mongodb.core.ReadOnlyMongodTransaction)1 WriteMongodTransaction (com.torodb.mongodb.core.WriteMongodTransaction)1 OplogManagerPersistException (com.torodb.mongodb.repl.OplogManager.OplogManagerPersistException)1 WriteOplogTransaction (com.torodb.mongodb.repl.OplogManager.WriteOplogTransaction)1 OplogApplyingException (com.torodb.mongodb.repl.oplogreplier.OplogOperationApplier.OplogApplyingException)1