forked from open-feature/java-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestStackedEmitCallsProvider.java
103 lines (86 loc) · 3.67 KB
/
TestStackedEmitCallsProvider.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
package dev.openfeature.sdk.testutils;
import dev.openfeature.sdk.EvaluationContext;
import dev.openfeature.sdk.EventProvider;
import dev.openfeature.sdk.Metadata;
import dev.openfeature.sdk.ProviderEvaluation;
import dev.openfeature.sdk.ProviderEvent;
import dev.openfeature.sdk.ProviderEventDetails;
import dev.openfeature.sdk.Value;
import java.util.function.Consumer;
public class TestStackedEmitCallsProvider extends EventProvider {
private final NestedBlockingEmitter nestedBlockingEmitter = new NestedBlockingEmitter(this::onProviderEvent);
@Override
public Metadata getMetadata() {
return () -> getClass().getSimpleName();
}
@Override
public void initialize(EvaluationContext evaluationContext) throws Exception {
synchronized (nestedBlockingEmitter) {
nestedBlockingEmitter.init();
while (!nestedBlockingEmitter.isReady()) {
try {
nestedBlockingEmitter.wait();
} catch (InterruptedException e) {
}
}
}
}
private void onProviderEvent(ProviderEvent providerEvent) {
synchronized (nestedBlockingEmitter) {
if (providerEvent == ProviderEvent.PROVIDER_READY) {
nestedBlockingEmitter.setReady();
/*
* This line deadlocked in the original implementation without the emitterExecutor see
* https://github.com/open-feature/java-sdk/issues/1299
*/
emitProviderReady(ProviderEventDetails.builder().build());
}
}
}
@Override
public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) {
throw new UnsupportedOperationException("Unimplemented method 'getBooleanEvaluation'");
}
@Override
public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) {
throw new UnsupportedOperationException("Unimplemented method 'getStringEvaluation'");
}
@Override
public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) {
throw new UnsupportedOperationException("Unimplemented method 'getIntegerEvaluation'");
}
@Override
public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) {
throw new UnsupportedOperationException("Unimplemented method 'getDoubleEvaluation'");
}
@Override
public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) {
throw new UnsupportedOperationException("Unimplemented method 'getObjectEvaluation'");
}
static class NestedBlockingEmitter {
private final Consumer<ProviderEvent> emitProviderEvent;
private volatile boolean isReady;
public NestedBlockingEmitter(Consumer<ProviderEvent> emitProviderEvent) {
this.emitProviderEvent = emitProviderEvent;
}
public void init() {
// run init outside monitored thread
new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
emitProviderEvent.accept(ProviderEvent.PROVIDER_READY);
})
.start();
}
public boolean isReady() {
return isReady;
}
public synchronized void setReady() {
isReady = true;
this.notifyAll();
}
}
}