forked from linkedin/parseq
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTestAsyncCallableTask.java
More file actions
125 lines (107 loc) · 3.44 KB
/
Copy pathTestAsyncCallableTask.java
File metadata and controls
125 lines (107 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package com.linkedin.parseq;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static com.linkedin.parseq.Tasks.par;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
/**
* @author wfender
* @version $Revision:$
*/
public class TestAsyncCallableTask extends BaseEngineTest
{
@Test
public void testConcurrentTasks() throws InterruptedException
{
// This test ensures that a single plan can run more than one blocking task
// at a time if the AsyncCallableTask feature is used.
final int size = 2; // Degree of parallelism
final CountDownLatch latch = new CountDownLatch(size);
final List<AsyncCallableTask<Void>> tasks = new ArrayList<AsyncCallableTask<Void>>(size);
for (int counter = 0; counter < size; counter++)
{
tasks.add(counter, new AsyncCallableTask<Void>(new Callable<Void>() {
@Override
public Void call() throws Exception
{
latch.countDown();
if (!latch.await(5, TimeUnit.SECONDS))
{
throw new TimeoutException("Latch should have reached 0 before timeout");
}
return null;
}
}));
}
final ParTask<Void> par = par(tasks);
getEngine().run(par);
assertTrue(par.await(5, TimeUnit.SECONDS));
assertEquals(2, par.getSuccessful().size());
assertEquals(2, par.getTasks().size());
assertEquals(2, par.get().size());
for (int counter = 0; counter < size; counter++)
{
assertTrue(tasks.get(counter).isDone());
assertFalse(tasks.get(counter).isFailed());
}
}
@Test
public void testThrowingCallable() throws InterruptedException
{
// Ensures that if a callable wrapped in an AsyncCallableTask throws that
// the wrapping task correctly reports the error state.
final Error error = new Error();
final Task<Void> task = new AsyncCallableTask<Void>(new Callable<Void>()
{
@Override
public Void call() throws Exception
{
throw error;
}
});
getEngine().run(task);
assertTrue(task.await(5, TimeUnit.SECONDS));
assertTrue(task.isDone());
assertTrue(task.isFailed());
assertEquals(error, task.getError());
}
@Test
public void testTaskWithoutExecutor() throws InterruptedException
{
final int numCores = Runtime.getRuntime().availableProcessors();
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(numCores + 1);
final Engine engine = new EngineBuilder()
.setTaskExecutor(scheduler)
.setTimerScheduler(scheduler)
.build();
try
{
final Task<Integer> task = new AsyncCallableTask<Integer>(new Callable<Integer>()
{
@Override
public Integer call() throws Exception
{
return 1;
}
});
engine.run(task);
assertTrue(task.await(5, TimeUnit.SECONDS));
assertTrue(task.isFailed());
assertTrue(task.getError() instanceof IllegalStateException);
}
finally
{
engine.shutdown();
engine.awaitTermination(1, TimeUnit.SECONDS);
scheduler.shutdownNow();
}
}
}