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);
}
}
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;
}
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;
}
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 + "");
}
}
}
}
}
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");
}
}
}
Aggregations