Search in sources :

Example 6 with TimeoutGuard

use of nl.nn.adapterframework.task.TimeoutGuard in project iaf by ibissource.

the class TransactionAttributePipeLineProcessor method processPipeLine.

@Override
public PipeLineResult processPipeLine(PipeLine pipeLine, String messageId, Message message, PipeLineSession pipeLineSession, String firstPipe) throws PipeRunException {
    try {
        // TransactionStatus txStatus = txManager.getTransaction(txDef);
        IbisTransaction itx = new IbisTransaction(txManager, pipeLine.getTxDef(), "pipeline of adapter [" + pipeLine.getOwner().getName() + "]");
        try {
            TimeoutGuard tg = new TimeoutGuard("pipeline of adapter [" + pipeLine.getOwner().getName() + "]");
            Throwable tCaught = null;
            try {
                tg.activateGuard(pipeLine.getTransactionTimeout());
                PipeLineResult pipeLineResult = pipeLineProcessor.processPipeLine(pipeLine, messageId, message, pipeLineSession, firstPipe);
                boolean mustRollback = false;
                if (pipeLineResult == null) {
                    mustRollback = true;
                    log.warn("Pipeline received null result for messageId [" + messageId + "], transaction (when present and active) will be rolled back");
                } else {
                    if (!pipeLineResult.isSuccessful()) {
                        mustRollback = true;
                        log.warn("Pipeline result state [" + pipeLineResult.getState() + "] for messageId [" + messageId + "] is not equal to [" + ExitState.SUCCESS + "], transaction (when present and active) will be rolled back");
                    }
                }
                if (mustRollback) {
                    try {
                        itx.setRollbackOnly();
                    } catch (Exception e) {
                        throw new PipeRunException(null, "Could not set RollBackOnly", e);
                    }
                }
                return pipeLineResult;
            } catch (Throwable t) {
                tCaught = t;
                throw tCaught;
            } finally {
                if (tg.cancel()) {
                    if (tCaught == null) {
                        throw new InterruptedException(tg.getDescription() + " was interrupted");
                    }
                    log.warn("Thread interrupted, but propagating other caught exception of type [" + ClassUtils.nameOf(tCaught) + "]");
                }
            }
        } catch (Throwable t) {
            log.debug("setting RollBackOnly for pipeline after catching exception");
            itx.setRollbackOnly();
            if (t instanceof Error) {
                throw (Error) t;
            } else if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else if (t instanceof PipeRunException) {
                throw (PipeRunException) t;
            } else {
                throw new PipeRunException(null, "Caught unknown checked exception", t);
            }
        } finally {
            // txManager.commit(txStatus);
            itx.commit();
        }
    } catch (RuntimeException e) {
        throw new PipeRunException(null, "RuntimeException calling PipeLine with tx attribute [" + pipeLine.getTransactionAttribute() + "]", e);
    }
}
Also used : IbisTransaction(nl.nn.adapterframework.core.IbisTransaction) PipeLineResult(nl.nn.adapterframework.core.PipeLineResult) PipeRunException(nl.nn.adapterframework.core.PipeRunException) TimeoutGuard(nl.nn.adapterframework.task.TimeoutGuard) PipeRunException(nl.nn.adapterframework.core.PipeRunException)

Example 7 with TimeoutGuard

use of nl.nn.adapterframework.task.TimeoutGuard in project iaf by ibissource.

the class Locker method acquire.

/**
 * Obtain the lock. If successful, the non-null lockId is returned.
 * If the lock cannot be obtained within the lock-timeout because it is held by another party, null is returned.
 * The lock wait timeout of the database can be overridden by setting lockWaitTimeout.
 * A wait timeout beyond the basic lockWaitTimeout and transactionTimeout can be set using numRetries in combination with retryDelay.
 */
public String acquire(MessageKeeper messageKeeper) throws JdbcException, SQLException, InterruptedException {
    try (Connection conn = getConnection()) {
        if (!getDbmsSupport().isTablePresent(conn, "IBISLOCK")) {
            if (isIgnoreTableNotExist()) {
                log.info("table [IBISLOCK] does not exist, ignoring lock");
                return LOCK_IGNORED;
            }
            throw new JdbcException("table [IBISLOCK] does not exist");
        }
    }
    String objectIdWithSuffix = null;
    int r = -1;
    while (objectIdWithSuffix == null && (numRetries == -1 || r < numRetries)) {
        r++;
        if (r == 0 && firstDelay > 0) {
            Thread.sleep(firstDelay);
        }
        if (r > 0) {
            Thread.sleep(retryDelay);
        }
        IbisTransaction itx = IbisTransaction.getTransaction(getTxManager(), getTxDef(), "locker [" + getName() + "]");
        try {
            Date date = new Date();
            objectIdWithSuffix = getObjectId();
            if (StringUtils.isNotEmpty(getDateFormatSuffix())) {
                String formattedDate = formatter.format(date);
                objectIdWithSuffix = objectIdWithSuffix.concat(formattedDate);
            }
            boolean timeout = false;
            log.debug("preparing to set lock [" + objectIdWithSuffix + "]");
            try (Connection conn = getConnection();
                PreparedStatement stmt = conn.prepareStatement(insertQuery)) {
                stmt.clearParameters();
                stmt.setString(1, objectIdWithSuffix);
                stmt.setString(2, getType());
                stmt.setString(3, Misc.getHostname());
                stmt.setTimestamp(4, new Timestamp(date.getTime()));
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                if (getType().equalsIgnoreCase("T")) {
                    cal.add(Calendar.HOUR_OF_DAY, getRetention());
                } else {
                    cal.add(Calendar.DAY_OF_MONTH, getRetention());
                }
                stmt.setTimestamp(5, new Timestamp(cal.getTime().getTime()));
                TimeoutGuard timeoutGuard = null;
                if (lockWaitTimeout > 0) {
                    timeoutGuard = new TimeoutGuard(lockWaitTimeout, "lockWaitTimeout") {

                        @Override
                        protected void abort() {
                            try {
                                stmt.cancel();
                            } catch (SQLException e) {
                                log.warn("Could not cancel statement", e);
                            }
                        }
                    };
                }
                try {
                    log.debug("lock [" + objectIdWithSuffix + "] inserting...");
                    stmt.executeUpdate();
                    log.debug("lock [" + objectIdWithSuffix + "] inserted executed");
                } finally {
                    if (timeoutGuard != null && timeoutGuard.cancel()) {
                        log.warn("Timeout obtaining lock [" + objectId + "]");
                        if (itx != null) {
                            itx.setRollbackOnly();
                        }
                        timeout = true;
                        objectIdWithSuffix = null;
                    }
                }
            } catch (Exception e) {
                if (itx != null) {
                    itx.setRollbackOnly();
                }
                objectIdWithSuffix = null;
                log.debug(getLogPrefix() + "error executing insert query (as part of locker): ", e);
                if (numRetries == -1 || r < numRetries) {
                    log.debug(getLogPrefix() + "will try again");
                } else {
                    log.debug(getLogPrefix() + "will not try again");
                    if (timeout || e instanceof SQLTimeoutException || e instanceof SQLException && getDbmsSupport().isConstraintViolation((SQLException) e)) {
                        String msg = "could not obtain lock: (" + e.getClass().getTypeName() + ") " + e.getMessage();
                        if (messageKeeper != null) {
                            messageKeeper.add(msg, MessageKeeperLevel.INFO);
                        }
                        log.info(getLogPrefix() + msg);
                    } else {
                        throw e;
                    }
                }
            }
        } finally {
            if (itx != null) {
                itx.commit();
            }
        }
    }
    return objectIdWithSuffix;
}
Also used : SQLException(java.sql.SQLException) Calendar(java.util.Calendar) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) JdbcException(nl.nn.adapterframework.jdbc.JdbcException) Timestamp(java.sql.Timestamp) TimeoutGuard(nl.nn.adapterframework.task.TimeoutGuard) Date(java.util.Date) SQLTimeoutException(java.sql.SQLTimeoutException) JdbcException(nl.nn.adapterframework.jdbc.JdbcException) ConfigurationException(nl.nn.adapterframework.configuration.ConfigurationException) SQLException(java.sql.SQLException) IbisTransaction(nl.nn.adapterframework.core.IbisTransaction) SQLTimeoutException(java.sql.SQLTimeoutException)

Example 8 with TimeoutGuard

use of nl.nn.adapterframework.task.TimeoutGuard in project iaf by ibissource.

the class ProcessUtil method executeCommand.

/**
 * Execute a command as a process in the operating system.
 * Timeout is passed in seconds, or 0 to wait indefinitely until the process ends
 */
public static String executeCommand(List command, int timeout) throws TimeoutException, SenderException {
    String output;
    String errors;
    final Process process;
    try {
        process = Runtime.getRuntime().exec((String[]) command.toArray(new String[0]));
    } catch (Throwable t) {
        throw new SenderException("Could not execute command [" + getCommandLine(command) + "]", t);
    }
    TimeoutGuard tg = new TimeoutGuard("ProcessUtil") {

        @Override
        protected void abort() {
            process.destroy();
        }
    };
    tg.activateGuard(timeout);
    try {
        // Wait until the process is completely finished, or timeout is expired
        process.waitFor();
    } catch (InterruptedException e) {
        if (tg.threadKilled()) {
            throw new TimeoutException("command [" + getCommandLine(command) + "] timed out", e);
        } else {
            throw new SenderException("command [" + getCommandLine(command) + "] interrupted while waiting for process", e);
        }
    } finally {
        tg.cancel();
    }
    // Read the output of the process
    try {
        output = readStream(process.getInputStream());
    } catch (IOException e) {
        throw new SenderException("Could not read output of command [" + getCommandLine(command) + "]", e);
    }
    // Read the errors of the process
    try {
        errors = readStream(process.getErrorStream());
    } catch (IOException e) {
        throw new SenderException("Could not read errors of command [" + getCommandLine(command) + "]", e);
    }
    // Throw an exception if the command returns an error exit value
    int exitValue = process.exitValue();
    if (exitValue != 0) {
        throw new SenderException("Nonzero exit value [" + exitValue + "] for command  [" + getCommandLine(command) + "], process output was [" + output + "], error output was [" + errors + "]");
    }
    if (StringUtils.isNotEmpty(errors)) {
        log.warn("command [" + getCommandLine(command) + "] had error output [" + errors + "]");
    }
    return output;
}
Also used : IOException(java.io.IOException) SenderException(nl.nn.adapterframework.core.SenderException) TimeoutGuard(nl.nn.adapterframework.task.TimeoutGuard) TimeoutException(nl.nn.adapterframework.core.TimeoutException)

Example 9 with TimeoutGuard

use of nl.nn.adapterframework.task.TimeoutGuard in project iaf by ibissource.

the class TransactionConnectorTest method runQuery.

private void runQuery(String query) throws SQLException {
    try (Connection con = getConnection()) {
        try (PreparedStatement stmt = con.prepareStatement(query)) {
            TimeoutGuard guard = new TimeoutGuard(3, "run child thread") {

                @Override
                protected void abort() {
                    try {
                        log.warn("--> TIMEOUT executing [" + query + "]");
                        stmt.cancel();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            };
            try {
                log.debug("runQuery thread [" + Thread.currentThread().getId() + "] query [" + query + "] ");
                stmt.execute();
            } finally {
                if (guard.cancel()) {
                    throw new SQLException("Interrupted [" + query + "");
                }
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) TimeoutGuard(nl.nn.adapterframework.task.TimeoutGuard)

Example 10 with TimeoutGuard

use of nl.nn.adapterframework.task.TimeoutGuard in project iaf by ibissource.

the class LockerTest method testTakeLockFailsAfterExecutingInsertInOtherThread.

@Test
public void testTakeLockFailsAfterExecutingInsertInOtherThread() throws Exception {
    cleanupLocks();
    locker.setTxManager(txManager);
    locker.setObjectId("myLocker");
    locker.configure();
    TimeoutGuard testTimeout = new TimeoutGuard(10, "Testtimeout");
    try {
        Semaphore otherReady = new Semaphore();
        Semaphore otherContinue = new Semaphore();
        Semaphore otherFinished = new Semaphore();
        LockerTester lockerTester = new LockerTester(txManager);
        lockerTester.setActionDone(otherReady);
        lockerTester.setWaitAfterAction(otherContinue);
        lockerTester.setFinalizeActionDone(otherFinished);
        lockerTester.start();
        otherReady.acquire();
        Timer timer = new Timer("let other thread commit after one second");
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                otherContinue.release();
            }
        }, 1000L);
        String objectId = locker.acquire();
        otherFinished.acquire();
        assertNull(objectId);
        assertNull(lockerTester.getCaught());
    } finally {
        if (testTimeout.cancel()) {
            fail("test timed out");
        }
    }
}
Also used : Timer(java.util.Timer) TimerTask(java.util.TimerTask) TimeoutGuard(nl.nn.adapterframework.task.TimeoutGuard) Test(org.junit.Test)

Aggregations

TimeoutGuard (nl.nn.adapterframework.task.TimeoutGuard)18 IbisTransaction (nl.nn.adapterframework.core.IbisTransaction)8 ConfigurationException (nl.nn.adapterframework.configuration.ConfigurationException)6 PipeRunException (nl.nn.adapterframework.core.PipeRunException)5 SenderException (nl.nn.adapterframework.core.SenderException)5 TimeoutException (nl.nn.adapterframework.core.TimeoutException)5 PipeLineResult (nl.nn.adapterframework.core.PipeLineResult)4 Test (org.junit.Test)4 IOException (java.io.IOException)3 Connection (java.sql.Connection)3 PreparedStatement (java.sql.PreparedStatement)3 SQLException (java.sql.SQLException)3 Date (java.util.Date)3 ListenerException (nl.nn.adapterframework.core.ListenerException)3 PipeRunResult (nl.nn.adapterframework.core.PipeRunResult)3 Message (nl.nn.adapterframework.stream.Message)3 TransactionStatus (org.springframework.transaction.TransactionStatus)3 HashMap (java.util.HashMap)2 Timer (java.util.Timer)2 TimerTask (java.util.TimerTask)2