/
ThreadLocalRunnerSupplier.java
106 lines (84 loc) · 3.04 KB
/
ThreadLocalRunnerSupplier.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
package cucumber.runner;
import cucumber.api.event.Event;
import cucumber.api.event.EventHandler;
import cucumber.runtime.BackendSupplier;
import io.cucumber.core.options.RunnerOptions;
/**
* Creates a distinct runner for each calling thread. Each runner has its own bus, backend- and glue-suppliers.
* <p>
* Each runners bus passes all events to the event bus of this supplier.
*/
public class ThreadLocalRunnerSupplier implements RunnerSupplier {
private final BackendSupplier backendSupplier;
private final RunnerOptions runnerOptions;
private final SynchronizedEventBus sharedEventBus;
private final ThreadLocal<Runner> runners = new ThreadLocal<Runner>() {
@Override
protected Runner initialValue() {
return createRunner();
}
};
public ThreadLocalRunnerSupplier(
RunnerOptions runnerOptions,
EventBus sharedEventBus,
BackendSupplier backendSupplier
) {
this.runnerOptions = runnerOptions;
this.sharedEventBus = SynchronizedEventBus.synchronize(sharedEventBus);
this.backendSupplier = backendSupplier;
}
@Override
public Runner get() {
return runners.get();
}
private Runner createRunner() {
return new Runner(new LocalEventBus(sharedEventBus), backendSupplier.get(), runnerOptions);
}
private static final class LocalEventBus extends AbstractEventBus {
private final SynchronizedEventBus parent;
LocalEventBus(final SynchronizedEventBus parent) {
this.parent = parent;
}
@Override
public Long getTime() {
return parent.getTime();
}
@Override
public void send(final Event event) {
super.send(event);
parent.send(event);
}
}
private static final class SynchronizedEventBus implements EventBus {
private final EventBus delegate;
static SynchronizedEventBus synchronize(EventBus eventBus) {
if (eventBus instanceof SynchronizedEventBus) {
return (SynchronizedEventBus) eventBus;
}
return new SynchronizedEventBus(eventBus);
}
private SynchronizedEventBus(final EventBus delegate) {
this.delegate = delegate;
}
@Override
public synchronized Long getTime() {
return delegate.getTime();
}
@Override
public synchronized void send(final Event event) {
delegate.send(event);
}
@Override
public synchronized void sendAll(final Iterable<Event> events) {
delegate.sendAll(events);
}
@Override
public synchronized <T extends Event> void registerHandlerFor(Class<T> eventType, EventHandler<T> handler) {
delegate.registerHandlerFor(eventType, handler);
}
@Override
public synchronized <T extends Event> void removeHandlerFor(Class<T> eventType, EventHandler<T> handler) {
delegate.removeHandlerFor(eventType, handler);
}
}
}