use of org.ak.trafficController.Task in project trafficController by amitkhosla.
the class AnnotationSupportImpl method addToTaskChainAsCalledFromParallel.
/**
* Add to task chain when Controlled called from parallel flow.
* @param joinPoint Join point
* @param controlled Controlled
* @param task Parallel Task
* @param taskExecutorPresent Is task executor present
* @param nameForTheTaskExecutor Name of task executor
* @param taskExecutor Task executor
* @return Task executor
*/
protected TaskExecutor addToTaskChainAsCalledFromParallel(ProceedingJoinPoint joinPoint, Controlled controlled, Task task, boolean taskExecutorPresent, String nameForTheTaskExecutor, TaskExecutor taskExecutor) {
int taskId = parallelJoinHelper.getObjectKeyForParalleldTask();
int parallelTaskId = ParallelJoinHelper.getParallelId();
logger.fine("already from same executor..so will be processed directly via different task.");
RunnableToBeExecuted runnableToBeExecuted = () -> {
ParallelJoinHelper.putObject(parallelTaskId, taskId, joinPoint.proceed());
};
// / TODO - IS this check required?
if (taskExecutorPresent) {
taskExecutor = task.getTaskExecutor();
} else {
runnableToBeExecuted = () -> {
try {
TaskExecutorsInUseThreadLocal.setTaskExecutor(nameForTheTaskExecutor);
Object result = joinPoint.proceed();
if (Objects.nonNull(result)) {
ParallelJoinHelper.putObject(parallelTaskId, taskId, result);
}
} finally {
TaskExecutorsInUseThreadLocal.removeTaskExecutor(nameForTheTaskExecutor);
}
};
}
String name = "ParallelId:" + parallelTaskId + " taskId:" + taskId + " " + getTaskNameFromJoinPoint(joinPoint);
org.ak.trafficController.Task.TaskType taskType = convertAnnotationTaskTypeToFrameworkTaskType(controlled.taskType());
Task thisTask;
if (taskType == org.ak.trafficController.Task.TaskType.NORMAL) {
thisTask = taskExecutor.of(runnableToBeExecuted);
} else {
thisTask = taskExecutor.slowOf(runnableToBeExecuted);
}
((ParallelTask) task).addTask(thisTask);
setThreadingDetailsIfAny(thisTask, controlled.threadDetailsDataExtractClass(), controlled.threadDetailsDataExtractMethodName(), controlled.threadDetailsProcessorClass(), controlled.threadDetailsProcessorMethodName(), controlled.threadDetailsCleanerClass(), controlled.threadDetailsCleanerMethodName());
return taskExecutor;
}
use of org.ak.trafficController.Task in project trafficController by amitkhosla.
the class AnnotationSupportImpl method runParallel.
/**
* Handles Parallel annotated methods.
* Parallel if annotated, all method calls to Controlled annotated methods is made in parallel. Join annotated method joins back the the result created by controlled annotated methods.
* It first execute the annotated method and creates task chain to be run in parallel followed by a joiner method which will join these results.
* Parallel should be used only where we are calling different methods annotated with controlled and in different class to allow AOP play its work.
* Output returned will be the output from Join operation or the last operation.
* @param joinPoint Join point
* @param parallel Parallel
* @return Return output of the operation
* @throws Throwable In case of any exception in processing
*/
@Around("execution(@org.ak.trafficController.annotations.api.Parallel * *(..)) && @annotation(parallel)")
public Object runParallel(ProceedingJoinPoint joinPoint, Parallel parallel) throws Throwable {
int currentParallelId = parallelId.incrementAndGet();
parallelJoinHelper.map.put(currentParallelId, new ConcurrentHashMap<>());
AtomicInteger taskId = new AtomicInteger(0);
AtomicInteger earlierParallelTaskId = new AtomicInteger(0);
Task originalTask = parallelJoinHelper.getTask();
boolean isSubParallelTask = originalTask != null;
if (isSubParallelTask) {
// this task is one task of parallel tasks.
taskId.set(parallelJoinHelper.getObjectKeyForParalleldTask());
earlierParallelTaskId.set(parallelJoinHelper.getParallelId());
}
ParallelJoinHelper.setParallelTaskId(currentParallelId);
// if (!isSubParallelTask) {
ExecutableTask thisParallelTask = TaskExecutor.getInstance().of(() -> {
});
setThreadingDetailsIfAny(thisParallelTask, parallel.threadDetailsDataExtractClass(), parallel.threadDetailsDataExtractMethodName(), parallel.threadDetailsProcessorClass(), parallel.threadDetailsProcessorMethodName(), parallel.threadDetailsCleanerClass(), parallel.threadDetailsCleanerMethodName());
thisParallelTask.setName("ParallelTask" + currentParallelId);
ParallelExecutingTask<Object> thenParallel = thisParallelTask.thenParallel(() -> {
});
thenParallel.setName("ParallelTaskName:" + currentParallelId);
// set dummy task
parallelJoinHelper.setTask(thenParallel);
// }
if (!isSubParallelTask) {
Object val = directParallelTaskHandling(joinPoint, currentParallelId, parallel);
return val;
} else {
joinPoint.proceed();
if (originalTask instanceof ParallelTask) {
subProcessHandling(currentParallelId, taskId, earlierParallelTaskId, originalTask, thisParallelTask);
}
return null;
}
}
use of org.ak.trafficController.Task in project trafficController by amitkhosla.
the class AnnotationSupportImpl method runAsync.
/**
* Handles Async operation where user is looking to submit something to get processed but calling thread should not wait for it.
* If called in Parallel flow, will be added as a async task/
* @param joinPoint Join point
* @param async Async
* @return Returns null if no exception
* @throws Throwable In case of exception in execution of annotated method
*/
@Around("execution(@org.ak.trafficController.annotations.api.Submit * *(..)) && @annotation(async)")
public Object runAsync(ProceedingJoinPoint joinPoint, Submit async) throws Throwable {
RunnableToBeExecuted taskToWorkOn = () -> {
try {
joinPoint.proceed();
} catch (Throwable e) {
logger.log(java.util.logging.Level.WARNING, "exception occured while running a submit request", e);
}
};
TaskExecutor taskExecutor = taskHelper.getTaskExecutor(async, joinPoint);
Task task = null;
TaskType taskType = async.taskType();
switch(taskType) {
case NORMAL:
task = taskExecutor.of(taskToWorkOn);
break;
case SLOW:
task = taskExecutor.slowOf(taskToWorkOn);
}
setThreadingDetailsIfAny(task, async.threadDetailsDataExtractClass(), async.threadDetailsDataExtractMethodName(), async.threadDetailsProcessorClass(), async.threadDetailsProcessorMethodName(), async.threadDetailsCleanerClass(), async.threadDetailsCleanerMethodName());
Task taskInThread = ParallelJoinHelper.getTask();
if (taskInThread == null) {
task.submit();
} else {
AtomicReference<Task> taskReference = new AtomicReference<Task>(task);
((ParallelTask) taskInThread).addRunnables(convertAnnotationTaskTypeToFrameworkTaskType(taskType), taskExecutor, () -> taskExecutor.enque(taskReference.get()));
}
return null;
}
use of org.ak.trafficController.Task in project trafficController by amitkhosla.
the class AnnotationSupportImpl method runControlled.
/**
* Handles controlled annotated methods.
* Controlled annotated methods are run in given executor. Current task waits for the execution to complete.
* This helps in throttling the execution, i.e., at a given time only specified number of executions are allowed for given process.
* In case it is running in Parallel flow, this just add it in task chain which will be handled in parallel.
* @param joinPoint Join point
* @param controlled Controlled
* @return Output of the annotated method
* @throws Throwable In case of exception in annotated mehtod
*/
@Around("execution(@org.ak.trafficController.annotations.api.Controlled * *(..)) && @annotation(controlled)")
public Object runControlled(ProceedingJoinPoint joinPoint, Controlled controlled) throws Throwable {
TaskExecutorDetails taskExecutorDetail = taskHelper.getTaskExecutor(controlled, joinPoint);
Task task = ParallelJoinHelper.getTask();
String nameForTheTaskExecutor = getNameForTaskExecutor(controlled, taskExecutorDetail);
boolean taskExecutorPresent = TaskExecutorsInUseThreadLocal.isTaskExecutorPresent(nameForTheTaskExecutor);
if (taskExecutorPresent) {
if (task == null) {
logger.fine("already from same executor..so processing directly.");
return joinPoint.proceed();
}
}
TaskExecutor taskExecutor = taskExecutorDetail.getTaskExecutor();
if (task != null) {
taskExecutor = addToTaskChainAsCalledFromParallel(joinPoint, controlled, task, taskExecutorPresent, nameForTheTaskExecutor, taskExecutor);
return null;
}
return executeControlled(joinPoint, controlled, nameForTheTaskExecutor, taskExecutor);
}
use of org.ak.trafficController.Task in project trafficController by amitkhosla.
the class AnnotationSupportImpl method directParallelTaskHandling.
/**
* Direct process handling. This method will be called while handling parallel in case where it is not called from another parallel flow.
* @param joinPoint Join point
* @param currentParallelId Current parallel id
* @param parallel Parallel
* @return Value of the tasks execution
* @throws Throwable In case of any issue in processing
*/
protected Object directParallelTaskHandling(ProceedingJoinPoint joinPoint, int currentParallelId, Parallel parallel) throws Throwable {
AtomicReference<Object> output = new AtomicReference<Object>(joinPoint.proceed());
Task cleanUpTask = parallelJoinHelper.getTask().then(() -> {
output.set(performCleanup(currentParallelId));
});
cleanUpTask.setName("Clean up task " + currentParallelId);
parallelJoinHelper.setTask(cleanUpTask);
// if (((MethodSignature) joinPoint.getSignature()).
ParallelJoinHelper.taskChain.get().start(parallel.waitTimeInMilliSeconds());
parallelJoinHelper.removeTask();
Object val = output.get();
if (val != null && val.getClass() == JoinResult.class) {
val = ((JoinResult) val).result;
}
return val;
}
Aggregations