forked from mnadeem/dependent-tasks-executor
-
Notifications
You must be signed in to change notification settings - Fork 70
Home
Nadeem Mohammad edited this page Aug 25, 2016
·
32 revisions
Dexecutor is a very light weight framework to execute dependent/Independent tasks in a reliable way, to do this it provides the minimal API.
- An API to add nodes in the graph (addDependency, addIndependent, addAsDependentOnAllLeafNodes, addAsDependencyToAllInitialNodes Later two are the hybrid version of the first two)
- and the other to execute the nodes in order.
<dependency>
<groupId>com.github.dexecutor</groupId>
<artifactId>dependent-tasks-executor</artifactId>
<version>0.0.1</version>
</dependency>
Refer this for other options/build tools
Lets take a look at an example, here is the content of DefaultDependentTasksExecutorIntegrationTest, which would help you understand the API
@Test
public void testDependentTaskExecution() {
DefaultDependentTasksExecutor<Integer, Integer> executor = newTaskExecutor();
executor.addDependency(1, 2);
executor.addDependency(1, 2);
executor.addDependency(1, 3);
executor.addDependency(3, 4);
executor.addDependency(3, 5);
executor.addDependency(3, 6);
//executor.addDependency(10, 2); // cycle
executor.addDependency(2, 7);
executor.addDependency(2, 9);
executor.addDependency(2, 8);
executor.addDependency(9, 10);
executor.addDependency(12, 13);
executor.addDependency(13, 4);
executor.addDependency(13, 14);
executor.addIndependent(11);
StringWriter writer = new StringWriter();
executor.print(writer);
System.out.println(writer);
executor.execute(ExecutionBehavior.RETRY_ONCE_TERMINATING);
System.out.println("*** Done ***");
}
private DefaultDependentTasksExecutor<Integer, Integer> newTaskExecutor() {
return new DefaultDependentTasksExecutor<Integer, Integer>(newExecutor(), new SleepyTaskProvider());
}
private ExecutorService newExecutor() {
return Executors.newFixedThreadPool(ThreadPoolUtil.ioIntesivePoolSize());
}
private static class SleepyTaskProvider implements TaskProvider<Integer, Integer> {
public Task<Integer, Integer> provid(final Integer id) {
return new Task<Integer, Integer>() {
public Integer execute() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return id;
}
};
}
}
As can be seen above, DefaultDependentTasksExecutorIntegrationTest requires two things
- Instance of
ExecutorService: API would use this Service to schedule tasks - Instance of
TaskProvider: API represents graph using just the basic information (could be task id), it consults theTaskProviderto provide the task when it comes to actual execution.
##There are two phases
-
Graph construction: When you say
executor.addDependency(1, 2)it means tasks1should finish before task2can start,executor.addIndependent(11)means as of now11does not depended on other nodes, but later time dependency to it can be added.
executor.addDependency(1, 2);
executor.addDependency(1, 3);
executor.addDependency(3, 4);
executor.addDependency(3, 5);
executor.addDependency(3, 6);
//executor.addDependency(10, 2); // cycle
executor.addDependency(2, 7);
executor.addDependency(2, 9);
executor.addDependency(2, 8);
executor.addDependency(9, 10);
executor.addDependency(12, 13);
executor.addDependency(13, 4);
executor.addDependency(13, 14);
executor.addIndependent(11);
Which would generate the following graph

executor.execute(ExecutionBehavior.RETRY_ONCE_TERMINATING);
21:18:02.080 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 1 node
21:18:02.089 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 11 node
21:18:02.089 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 12 node
21:18:02.091 [pool-1-thread-2] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 11
21:18:02.091 [pool-1-thread-3] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 12
21:18:02.091 [pool-1-thread-1] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 1
21:18:02.592 [pool-1-thread-1] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 1, Execution Done!
21:18:02.594 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 1 done
21:18:02.594 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 2 node
21:18:02.594 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 3 node
21:18:02.595 [pool-1-thread-2] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 11, Execution Done!
21:18:02.595 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 11 done
21:18:02.597 [pool-1-thread-5] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 3
21:18:02.599 [pool-1-thread-3] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 12, Execution Done!
21:18:02.599 [pool-1-thread-4] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 2
21:18:02.599 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 12 done
21:18:02.599 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 13 node
21:18:02.600 [pool-1-thread-6] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 13
21:18:03.099 [pool-1-thread-4] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 2, Execution Done!
21:18:03.099 [pool-1-thread-5] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 3, Execution Done!
21:18:03.099 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 2 done
21:18:03.099 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 7 node
21:18:03.099 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 9 node
21:18:03.100 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 8 node
21:18:03.100 [pool-1-thread-7] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 7
21:18:03.100 [pool-1-thread-8] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 9
21:18:03.100 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 3 done
21:18:03.101 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 159 - node 4 depends on [3, 13]
21:18:03.101 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 5 node
21:18:03.101 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 6 node
21:18:03.102 [pool-1-thread-11] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 6
21:18:03.103 [pool-1-thread-9] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 8
21:18:03.104 [pool-1-thread-6] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 13, Execution Done!
21:18:03.105 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 13 done
21:18:03.105 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 4 node
21:18:03.106 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 14 node
21:18:03.107 [pool-1-thread-10] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 5
21:18:03.108 [pool-1-thread-13] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 14
21:18:03.109 [pool-1-thread-12] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 4
21:18:03.600 [pool-1-thread-7] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 7, Execution Done!
21:18:03.601 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 7 done
21:18:03.602 [pool-1-thread-8] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 9, Execution Done!
21:18:03.603 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 9 done
21:18:03.603 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doExecute 155 - Going to schedule 10 node
21:18:03.604 [pool-1-thread-14] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 288 - Executing Node # 10
21:18:03.605 [pool-1-thread-9] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 8, Execution Done!
21:18:03.606 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 8 done
21:18:03.607 [pool-1-thread-11] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 6, Execution Done!
21:18:03.608 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 6 done
21:18:03.609 [pool-1-thread-10] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 5, Execution Done!
21:18:03.610 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 5 done
21:18:03.611 [pool-1-thread-13] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 14, Execution Done!
21:18:03.612 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 14 done
21:18:03.613 [pool-1-thread-12] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 4, Execution Done!
21:18:03.614 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 4 done
21:18:04.105 [pool-1-thread-14] DEBUG c.g.d.e.DefaultDependentTasksExecutor$ExecutorTask.execute 293 - Node # 10, Execution Done!
21:18:04.106 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.doWaitForExecution 181 - Processing of node 10 done
21:18:04.106 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.execute 138 - Total Time taken to process 14 jobs is 2027 ms.
21:18:04.106 [main] DEBUG c.g.d.e.DefaultDependentTasksExecutor.execute 139 - Processed Nodes Ordering [1, 11, 12, 2, 3, 13, 7, 9, 8, 6, 5, 14, 4, 10]
Refer this project for more complex example