use of co.cask.cdap.api.annotation.TransactionControl in project cdap by caskdata.
the class CustomActionExecutor method executeCustomAction.
private void executeCustomAction() throws Exception {
try {
customActionContext.setState(new ProgramState(ProgramStatus.INITIALIZING, null));
// AbstractCustomAction implements final initialize(context) and requires subclass to
// implement initialize(), whereas programs that directly implement CustomAction can
// override initialize(context)
TransactionControl txControl = customAction instanceof AbstractCustomAction ? Transactions.getTransactionControl(TransactionControl.IMPLICIT, AbstractCustomAction.class, customAction, "initialize") : Transactions.getTransactionControl(TransactionControl.IMPLICIT, CustomAction.class, customAction, "initialize", CustomActionContext.class);
customActionContext.initializeProgram(customAction, customActionContext, txControl, false);
customActionContext.setState(new ProgramState(ProgramStatus.RUNNING, null));
customActionContext.executeChecked(new AbstractContext.ThrowingRunnable() {
@Override
public void run() throws Exception {
customAction.run();
}
});
customActionContext.setState(new ProgramState(ProgramStatus.COMPLETED, null));
} catch (Throwable t) {
customActionContext.setState(new ProgramState(ProgramStatus.FAILED, Throwables.getRootCause(t).getMessage()));
Throwables.propagateIfPossible(t, Exception.class);
throw Throwables.propagate(t);
} finally {
TransactionControl txControl = Transactions.getTransactionControl(TransactionControl.IMPLICIT, CustomAction.class, customAction, "destroy");
customActionContext.destroyProgram(customAction, customActionContext, txControl, false);
}
}
use of co.cask.cdap.api.annotation.TransactionControl in project cdap by caskdata.
the class BodyConsumerAdapter method onError.
/**
* Calls the {@link HttpContentConsumer#onError(HttpServiceResponder, Throwable)} method from a transaction.
*/
private void onError(final Throwable cause, final DelayedHttpServiceResponder responder) {
if (completed) {
return;
}
// To the HttpContentConsumer, once onError is called, no other methods will be triggered
completed = true;
TransactionControl txCtrl = Transactions.getTransactionControl(TransactionControl.IMPLICIT, HttpContentConsumer.class, delegate, "onError", HttpServiceResponder.class, Throwable.class);
try {
if (TransactionControl.IMPLICIT == txCtrl) {
transactional.execute(new TxRunnable() {
@Override
public void run(DatasetContext context) throws Exception {
delegate.onError(responder, cause);
}
});
} else {
delegate.onError(responder, cause);
}
} catch (Throwable t) {
responder.setTransactionFailureResponse(t);
LOG.warn("Exception in calling HttpContentConsumer.onError", t);
} finally {
try {
responder.execute(false);
} finally {
if (!responder.hasContentProducer()) {
contextReleaser.cancel();
}
}
}
}
use of co.cask.cdap.api.annotation.TransactionControl in project cdap by caskdata.
the class SparkRuntimeService method initialize.
/**
* Calls the {@link Spark#beforeSubmit(SparkClientContext)} for the pre 3.5 Spark programs, calls
* the {@link ProgramLifecycle#initialize} otherwise.
*/
@SuppressWarnings("unchecked")
private void initialize() throws Exception {
// AbstractSpark implements final initialize(context) and requires subclass to
// implement initialize(), whereas programs that directly implement Spark have
// the option to override initialize(context) (if they implement ProgramLifeCycle)
final TransactionControl txControl = spark instanceof AbstractSpark ? Transactions.getTransactionControl(TransactionControl.IMPLICIT, AbstractSpark.class, spark, "initialize") : spark instanceof ProgramLifecycle ? Transactions.getTransactionControl(TransactionControl.IMPLICIT, Spark.class, spark, "initialize", SparkClientContext.class) : TransactionControl.IMPLICIT;
TxRunnable runnable = new TxRunnable() {
@Override
public void run(DatasetContext ctxt) throws Exception {
Cancellable cancellable = SparkRuntimeUtils.setContextClassLoader(new SparkClassLoader(runtimeContext));
try {
context.setState(new ProgramState(ProgramStatus.INITIALIZING, null));
if (spark instanceof ProgramLifecycle) {
((ProgramLifecycle) spark).initialize(context);
} else {
spark.beforeSubmit(context);
}
} finally {
cancellable.cancel();
}
}
};
if (TransactionControl.IMPLICIT == txControl) {
context.execute(runnable);
} else {
runnable.run(context);
}
}
use of co.cask.cdap.api.annotation.TransactionControl in project cdap by caskdata.
the class Transactions method getTransactionControl.
/**
* Determines the transaction control of a method, as (optionally) annotated with @TransactionPolicy.
* If the program's class does not implement the method, the superclass is inspected up to and including
* the given base class.
*
* @param defaultValue returned if no annotation is present
* @param baseClass upper bound for the super classes to be inspected
* @param program the program
* @param methodName the name of the method
* @param params the parameter types of the method
*
* @return the transaction control annotated for the method of the program class or its nearest superclass that
* is annotated; or defaultValue if no annotation is present in any of the superclasses
*/
public static TransactionControl getTransactionControl(TransactionControl defaultValue, Class<?> baseClass, Object program, String methodName, Class<?>... params) {
Class<?> cls = program.getClass();
while (Object.class != cls) {
// we know that Object cannot have this annotation :)
TransactionControl txControl = getTransactionControl(cls, methodName, params);
if (txControl != null) {
return txControl;
}
if (cls == baseClass) {
// reached bounding superclass
break;
}
cls = cls.getSuperclass();
}
// if we reach this point, then none of the super classes had an annotation for the method
for (Class<?> interf : program.getClass().getInterfaces()) {
TransactionControl txControl = getTransactionControl(interf, methodName, params);
if (txControl != null) {
return txControl;
}
}
return defaultValue;
}
use of co.cask.cdap.api.annotation.TransactionControl in project cdap by caskdata.
the class MapReduceRuntimeService method beforeSubmit.
/**
* For pre 3.5 MapReduce programs, calls the {@link MapReduce#beforeSubmit(MapReduceContext)} method.
* For MapReduce programs created after 3.5, calls the initialize method of the {@link ProgramLifecycle}.
* This method also sets up the Input/Output within the same transaction.
*/
@SuppressWarnings("unchecked")
private void beforeSubmit(final Job job) throws Exception {
// AbstractMapReduce implements final initialize(context) and requires subclass to
// implement initialize(), whereas programs that directly implement MapReduce have
// the option to override initialize(context) (if they implement ProgramLifeCycle)
final TransactionControl txControl = mapReduce instanceof AbstractMapReduce ? Transactions.getTransactionControl(TransactionControl.IMPLICIT, AbstractMapReduce.class, mapReduce, "initialize") : mapReduce instanceof ProgramLifecycle ? Transactions.getTransactionControl(TransactionControl.IMPLICIT, MapReduce.class, mapReduce, "initialize", MapReduceContext.class) : TransactionControl.IMPLICIT;
if (TransactionControl.EXPLICIT == txControl) {
doInitialize(job);
} else {
Transactionals.execute(context, new TxRunnable() {
@Override
public void run(DatasetContext context) throws Exception {
doInitialize(job);
}
}, Exception.class);
}
ClassLoader oldClassLoader = ClassLoaders.setContextClassLoader(job.getConfiguration().getClassLoader());
try {
// set input/outputs info, and get one of the configured mapper's TypeToken
TypeToken<?> mapperTypeToken = setInputsIfNeeded(job);
setOutputsIfNeeded(job);
setOutputClassesIfNeeded(job, mapperTypeToken);
setMapOutputClassesIfNeeded(job, mapperTypeToken);
} finally {
ClassLoaders.setContextClassLoader(oldClassLoader);
}
}
Aggregations