/
StatementTimeoutExecutor.java
117 lines (101 loc) · 3.88 KB
/
StatementTimeoutExecutor.java
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
package fitnesse.slim;
import java.util.concurrent.*;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static java.util.concurrent.TimeUnit.SECONDS;
public class StatementTimeoutExecutor implements StatementExecutorInterface {
private final StatementExecutorInterface inner;
private final Integer timeout;
private final ExecutorService service;
private StatementTimeoutExecutor(StatementExecutorInterface inner, Integer timeout, ExecutorService service) {
this.inner = inner;
this.timeout = timeout;
this.service = service;
}
public static StatementExecutorInterface decorate(StatementExecutorInterface inner, Integer timeout) {
return decorate(inner, timeout, newSingleThreadExecutor());
}
public static StatementExecutorInterface decorate(StatementExecutorInterface inner, Integer timeout, ExecutorService service) {
return new StatementTimeoutExecutor(inner, timeout, service);
}
@Override
public void setVariable(final String name, final Object value) {
inner.setVariable(name, value);
}
@Override
public Object getInstance(String instanceName) {
return inner.getInstance(instanceName);
}
@Override
public boolean stopHasBeenRequested() {
return inner.stopHasBeenRequested();
}
@Override
public void reset() {
inner.reset();
}
@Override
public void setInstance(String actorInstanceName, Object actor) {
inner.setInstance(actorInstanceName, actor);
}
@Override
public void addPath(String path) throws SlimException {
inner.addPath(path);
}
@Override
public void create(final String instanceName, final String className, final Object... constructorArgs) throws SlimException {
Future<?> submit = service.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
inner.create(instanceName, className, constructorArgs);
return true;
}
});
try {
getWithTimeout(submit);
} catch (TimeoutException e) {
throw new SlimException("timed out creating instance, instanceName : " + instanceName + ", classname : " + className + ", statementTimeout : " + timeout + " seconds");
}
}
@Override
public Object callAndAssign(final String symbolName, final String instanceName, final String methodsName, final Object... arguments) throws SlimException {
Future<Object> submit = service.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
return inner.callAndAssign(symbolName, instanceName, methodsName, arguments);
}
});
try {
return getWithTimeout(submit);
} catch (TimeoutException e) {
throw new SlimException("timed out in callAndAssign, symbolName : " + symbolName + ", instanceName : " + instanceName + ", methodsName : " + methodsName + ", statementTimeout : " + timeout + " seconds");
}
}
@Override
public Object call(final String instanceName, final String methodName, final Object... arguments) throws SlimException {
Future<Object> submit = service.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
return inner.call(instanceName, methodName, arguments);
}
});
try {
return getWithTimeout(submit);
} catch (TimeoutException e) {
throw new SlimException("timed out in call, instanceName : " + instanceName + ", methodName : " + methodName + ", statementTimeout : " + timeout + " seconds");
}
}
private <T> T getWithTimeout(Future<T> submit) throws SlimException, TimeoutException {
try {
return submit.get(timeout, SECONDS);
} catch (InterruptedException e) {
throw new SlimException(e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof SlimException) {
throw (SlimException) cause;
} else {
throw new SlimException(e.getCause());
}
}
}
}