use of org.apache.activemq.artemis.core.io.IOCallback in project activemq-artemis by apache.
the class TransactionCallback method done.
@Override
public void done() {
countLatch.countDown();
if (++done == up.get() && delegateCompletion != null) {
final IOCallback delegateToCall = delegateCompletion;
// We need to set the delegateCompletion to null first or blocking commits could miss a callback
// What would affect mainly tests
delegateCompletion = null;
delegateToCall.done();
}
}
use of org.apache.activemq.artemis.core.io.IOCallback in project activemq-artemis by apache.
the class TransactionImpl method internalRollback.
private void internalRollback() throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("TransactionImpl::internalRollback " + this);
}
beforeRollback();
try {
doRollback();
state = State.ROLLEDBACK;
} catch (IllegalStateException e) {
// Something happened before and the TX didn't make to the Journal / Storage
// We will like to execute afterRollback and clear anything pending
ActiveMQServerLogger.LOGGER.failedToPerformRollback(e);
}
// We want to make sure that nothing else gets done after the commit is issued
// this will eliminate any possibility or races
final List<TransactionOperation> operationsToComplete = this.operations;
this.operations = null;
final List<TransactionOperation> storeOperationsToComplete = this.storeOperations;
this.storeOperations = null;
// We use the Callback even for non persistence
// If we are using non-persistence with replication, the replication manager will have
// to execute this runnable in the correct order
storageManager.afterCompleteOperations(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
ActiveMQServerLogger.LOGGER.ioErrorOnTX(errorCode, errorMessage);
}
@Override
public void done() {
afterRollback(operationsToComplete);
}
});
if (storeOperationsToComplete != null) {
storageManager.afterStoreOperations(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
ActiveMQServerLogger.LOGGER.ioErrorOnTX(errorCode, errorMessage);
}
@Override
public void done() {
afterRollback(storeOperationsToComplete);
}
});
}
}
use of org.apache.activemq.artemis.core.io.IOCallback in project activemq-artemis by apache.
the class TransactionImpl method prepare.
@Override
public void prepare() throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("TransactionImpl::prepare::" + this);
}
storageManager.readLock();
try {
synchronized (timeoutLock) {
if (isEffective()) {
logger.debug("TransactionImpl::prepare::" + this + " is being ignored");
return;
}
if (state == State.ROLLBACK_ONLY) {
if (logger.isTraceEnabled()) {
logger.trace("TransactionImpl::prepare::rollbackonly, rollingback " + this);
}
internalRollback();
if (exception != null) {
throw exception;
} else {
// Do nothing
return;
}
} else if (state != State.ACTIVE) {
throw new IllegalStateException("Transaction is in invalid state " + state);
}
if (xid == null) {
throw new IllegalStateException("Cannot prepare non XA transaction");
}
beforePrepare();
storageManager.prepare(id, xid);
state = State.PREPARED;
// We use the Callback even for non persistence
// If we are using non-persistence with replication, the replication manager will have
// to execute this runnable in the correct order
storageManager.afterCompleteOperations(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
ActiveMQServerLogger.LOGGER.ioErrorOnTX(errorCode, errorMessage);
}
@Override
public void done() {
afterPrepare();
}
});
}
} finally {
storageManager.readUnLock();
}
}
use of org.apache.activemq.artemis.core.io.IOCallback in project activemq-artemis by apache.
the class TransactionImpl method commit.
@Override
public void commit(final boolean onePhase) throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("TransactionImpl::commit::" + this);
}
synchronized (timeoutLock) {
if (state == State.COMMITTED) {
// I don't think this could happen, but just in case
logger.debug("TransactionImpl::commit::" + this + " is being ignored");
return;
}
if (state == State.ROLLBACK_ONLY) {
internalRollback();
if (exception != null) {
throw exception;
} else {
// Do nothing
return;
}
}
if (xid != null) {
if (onePhase && state != State.ACTIVE || !onePhase && state != State.PREPARED) {
throw new ActiveMQIllegalStateException("Transaction is in invalid state " + state);
}
} else {
if (state != State.ACTIVE) {
throw new ActiveMQIllegalStateException("Transaction is in invalid state " + state);
}
}
beforeCommit();
doCommit();
// We want to make sure that nothing else gets done after the commit is issued
// this will eliminate any possibility or races
final List<TransactionOperation> operationsToComplete = this.operations;
this.operations = null;
// We use the Callback even for non persistence
// If we are using non-persistence with replication, the replication manager will have
// to execute this runnable in the correct order
// This also will only use a different thread if there are any IO pending.
// If the IO finished early by the time we got here, we won't need an executor
storageManager.afterCompleteOperations(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
ActiveMQServerLogger.LOGGER.ioErrorOnTX(errorCode, errorMessage);
}
@Override
public void done() {
afterCommit(operationsToComplete);
}
});
final List<TransactionOperation> storeOperationsToComplete = this.storeOperations;
this.storeOperations = null;
if (storeOperationsToComplete != null) {
storageManager.afterStoreOperations(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
ActiveMQServerLogger.LOGGER.ioErrorOnTX(errorCode, errorMessage);
}
@Override
public void done() {
afterCommit(storeOperationsToComplete);
}
});
}
}
}
use of org.apache.activemq.artemis.core.io.IOCallback in project activemq-artemis by apache.
the class QueueImpl method moveBetweenSnFQueues.
@SuppressWarnings({ "ArrayToString", "ArrayToStringConcatenation" })
private void moveBetweenSnFQueues(final SimpleString queueSuffix, final Transaction tx, final MessageReference ref) throws Exception {
Message copyMessage = makeCopy(ref, false, false);
byte[] oldRouteToIDs = null;
String targetNodeID;
Binding targetBinding;
// remove the old route
for (SimpleString propName : copyMessage.getPropertyNames()) {
if (propName.startsWith(Message.HDR_ROUTE_TO_IDS)) {
oldRouteToIDs = (byte[]) copyMessage.removeProperty(propName.toString());
// don't use Arrays.toString(..) here
final String hashcodeToString = oldRouteToIDs.toString();
logger.debug("Removed property from message: " + propName + " = " + hashcodeToString + " (" + ByteBuffer.wrap(oldRouteToIDs).getLong() + ")");
// there should only be one of these properties so potentially save some loop iterations
break;
}
}
ByteBuffer oldBuffer = ByteBuffer.wrap(oldRouteToIDs);
RoutingContext routingContext = new RoutingContextImpl(tx);
/* this algorithm will look at the old route and find the new remote queue bindings where the messages should go
* and route them there directly
*/
while (oldBuffer.hasRemaining()) {
long oldQueueID = oldBuffer.getLong();
// look at all the bindings
Pair<String, Binding> result = locateTargetBinding(queueSuffix, copyMessage, oldQueueID);
targetBinding = result.getB();
targetNodeID = result.getA();
if (targetBinding == null) {
ActiveMQServerLogger.LOGGER.unableToFindTargetQueue(targetNodeID);
} else {
logger.debug("Routing on binding: " + targetBinding);
targetBinding.route(copyMessage, routingContext);
}
}
postOffice.processRoute(copyMessage, routingContext, false);
ref.handled();
acknowledge(tx, ref);
storageManager.afterCompleteOperations(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
ActiveMQServerLogger.LOGGER.ioErrorRedistributing(errorCode, errorMessage);
}
@Override
public void done() {
deliverAsync();
}
});
}
Aggregations