Skip to content

Commit ebcb5ce

Browse files
committed
fix: Use ConcurrentHashMap for InMemoryProvider
Signed-off-by: Ryan Prayogo <[email protected]>
1 parent 61d821a commit ebcb5ce

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import java.util.ArrayList;
44
import java.util.Arrays;
5-
import java.util.HashMap;
65
import java.util.HashSet;
76
import java.util.Map;
87
import java.util.Set;
8+
import java.util.concurrent.ConcurrentHashMap;
99

1010
import dev.openfeature.sdk.EvaluationContext;
1111
import dev.openfeature.sdk.EventProvider;
@@ -44,7 +44,7 @@ public Metadata getMetadata() {
4444
}
4545

4646
public InMemoryProvider(Map<String, Flag<?>> flags) {
47-
this.flags = new HashMap<>(flags);
47+
this.flags = new ConcurrentHashMap<>(flags);
4848
}
4949

5050
/**
@@ -67,7 +67,7 @@ public void updateFlags(Map<String, Flag<?>> flags) {
6767
Set<String> flagsChanged = new HashSet<>();
6868
flagsChanged.addAll(this.flags.keySet());
6969
flagsChanged.addAll(flags.keySet());
70-
this.flags = new HashMap<>(flags);
70+
this.flags = new ConcurrentHashMap<>(flags);
7171
ProviderEventDetails details = ProviderEventDetails.builder()
7272
.flagsChanged(new ArrayList<>(flagsChanged))
7373
.message("flags changed")

src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import java.util.HashMap;
1616
import java.util.Map;
17+
import java.util.concurrent.ExecutorService;
18+
import java.util.concurrent.Executors;
1719

1820
import static dev.openfeature.sdk.Structure.mapToStructure;
1921
import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags;
@@ -105,4 +107,23 @@ void shouldThrowIfNotInitialized() {
105107
// ErrorCode.PROVIDER_NOT_READY should be returned when evaluated via the client
106108
assertThrows(ProviderNotReadyError.class, ()-> inMemoryProvider.getBooleanEvaluation("fail_not_initialized", false, new ImmutableContext()));
107109
}
110+
111+
@Test
112+
void multithreadedTest() {
113+
ExecutorService executorService = Executors.newFixedThreadPool(100);
114+
for (int i = 0; i < 10000; i++) {
115+
String flagKey = "multithreadedFlag" + i;
116+
executorService.submit(() -> {
117+
provider.updateFlag(flagKey, Flag.builder()
118+
.variant("on", true)
119+
.variant("off", false)
120+
.defaultVariant("on")
121+
.build());
122+
});
123+
}
124+
125+
for (int i = 0; i < 10000; i++) {
126+
assertTrue(client.getBooleanValue("multithreadedFlag" + i, false));
127+
}
128+
}
108129
}

0 commit comments

Comments
 (0)