Search in sources :

Example 1 with Task

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;
}
Also used : RunnableToBeExecuted(org.ak.trafficController.RunnableToBeExecuted) ParallelTask(org.ak.trafficController.ParallelTask) ParallelExecutingTask(org.ak.trafficController.ParallelExecutingTask) ExecutableTask(org.ak.trafficController.ExecutableTask) Task(org.ak.trafficController.Task) UnlinkedTask(org.ak.trafficController.UnlinkedTask) ParallelTask(org.ak.trafficController.ParallelTask) ProceedingJoinPoint(org.aspectj.lang.ProceedingJoinPoint)

Example 2 with Task

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;
    }
}
Also used : ParallelTask(org.ak.trafficController.ParallelTask) ParallelExecutingTask(org.ak.trafficController.ParallelExecutingTask) ExecutableTask(org.ak.trafficController.ExecutableTask) Task(org.ak.trafficController.Task) UnlinkedTask(org.ak.trafficController.UnlinkedTask) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutableTask(org.ak.trafficController.ExecutableTask) ParallelTask(org.ak.trafficController.ParallelTask) ProceedingJoinPoint(org.aspectj.lang.ProceedingJoinPoint) Around(org.aspectj.lang.annotation.Around)

Example 3 with Task

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;
}
Also used : RunnableToBeExecuted(org.ak.trafficController.RunnableToBeExecuted) TaskExecutor(org.ak.trafficController.TaskExecutor) ParallelTask(org.ak.trafficController.ParallelTask) ParallelExecutingTask(org.ak.trafficController.ParallelExecutingTask) ExecutableTask(org.ak.trafficController.ExecutableTask) Task(org.ak.trafficController.Task) UnlinkedTask(org.ak.trafficController.UnlinkedTask) TaskType(org.ak.trafficController.annotations.api.TaskType) AtomicReference(java.util.concurrent.atomic.AtomicReference) ParallelTask(org.ak.trafficController.ParallelTask) Around(org.aspectj.lang.annotation.Around)

Example 4 with Task

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);
}
Also used : ParallelTask(org.ak.trafficController.ParallelTask) ParallelExecutingTask(org.ak.trafficController.ParallelExecutingTask) ExecutableTask(org.ak.trafficController.ExecutableTask) Task(org.ak.trafficController.Task) UnlinkedTask(org.ak.trafficController.UnlinkedTask) TaskExecutor(org.ak.trafficController.TaskExecutor) Around(org.aspectj.lang.annotation.Around)

Example 5 with Task

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;
}
Also used : ParallelTask(org.ak.trafficController.ParallelTask) ParallelExecutingTask(org.ak.trafficController.ParallelExecutingTask) ExecutableTask(org.ak.trafficController.ExecutableTask) Task(org.ak.trafficController.Task) UnlinkedTask(org.ak.trafficController.UnlinkedTask) AtomicReference(java.util.concurrent.atomic.AtomicReference)

Aggregations

ExecutableTask (org.ak.trafficController.ExecutableTask)7 ParallelExecutingTask (org.ak.trafficController.ParallelExecutingTask)7 ParallelTask (org.ak.trafficController.ParallelTask)7 Task (org.ak.trafficController.Task)7 UnlinkedTask (org.ak.trafficController.UnlinkedTask)7 Around (org.aspectj.lang.annotation.Around)4 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 ProceedingJoinPoint (org.aspectj.lang.ProceedingJoinPoint)3 RunnableToBeExecuted (org.ak.trafficController.RunnableToBeExecuted)2 TaskExecutor (org.ak.trafficController.TaskExecutor)2 ArrayList (java.util.ArrayList)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 TaskType (org.ak.trafficController.annotations.api.TaskType)1