Skip to content

Commit 1977286

Browse files
authored
Restored test TenantTest#test2 after implementing a new method caching strategy in fault tolerance. (#8832)
1 parent 0b76c6c commit 1977286

File tree

2 files changed

+37
-6
lines changed
  • microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance
  • tests/functional/request-scope/src/test/java/io/helidon/tests/functional/requestscope

2 files changed

+37
-6
lines changed

microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/MethodInvoker.java

+37-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023 Oracle and/or its affiliates.
2+
* Copyright (c) 2020, 2024 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,15 +18,17 @@
1818
import java.lang.reflect.Method;
1919
import java.time.Duration;
2020
import java.util.Arrays;
21+
import java.util.HashMap;
22+
import java.util.Map;
2123
import java.util.Objects;
2224
import java.util.concurrent.CancellationException;
2325
import java.util.concurrent.CompletableFuture;
2426
import java.util.concurrent.CompletionStage;
25-
import java.util.concurrent.ConcurrentHashMap;
2627
import java.util.concurrent.ExecutionException;
2728
import java.util.concurrent.Future;
2829
import java.util.concurrent.atomic.AtomicBoolean;
2930
import java.util.concurrent.locks.ReentrantLock;
31+
import java.util.function.Function;
3032
import java.util.function.Supplier;
3133

3234
import io.helidon.common.context.Context;
@@ -86,7 +88,8 @@ class MethodInvoker implements FtSupplier<Object> {
8688
* caches the FT handler as well as some additional variables. This mapping must
8789
* be shared by all instances of this class.
8890
*/
89-
private static final ConcurrentHashMap<MethodStateKey, MethodState> METHOD_STATES = new ConcurrentHashMap<>();
91+
private static final MethodStateCache METHOD_STATES = new MethodStateCache();
92+
9093
/**
9194
* The method being intercepted.
9295
*/
@@ -693,7 +696,7 @@ private static class MethodState {
693696
/**
694697
* A key used to lookup {@code MethodState} instances, which include FT handlers.
695698
* A class loader is necessary to support multiple applications as seen in the TCKs.
696-
* The method class in necessary given that the same method can inherited by different
699+
* The method class in necessary given that the same method can inherit by different
697700
* classes with different FT annotations and should not share handlers. Finally, the
698701
* method is main part of the key.
699702
*/
@@ -727,4 +730,34 @@ public int hashCode() {
727730
return Objects.hash(classLoader, methodClass, method);
728731
}
729732
}
733+
734+
/**
735+
* Used instead of a {@link java.util.concurrent.ConcurrentHashMap} to avoid some
736+
* locking problems.
737+
*/
738+
private static class MethodStateCache {
739+
740+
private final ReentrantLock lock = new ReentrantLock();
741+
private final Map<MethodStateKey, MethodState> cache = new HashMap<>();
742+
743+
MethodState computeIfAbsent(MethodStateKey key, Function<MethodStateKey, MethodState> function) {
744+
lock.lock();
745+
try {
746+
MethodState methodState = cache.get(key);
747+
if (methodState != null) {
748+
return methodState;
749+
}
750+
MethodState newMethodState = function.apply(key);
751+
Objects.requireNonNull(newMethodState);
752+
cache.put(key, newMethodState);
753+
return newMethodState;
754+
} finally {
755+
lock.unlock();
756+
}
757+
}
758+
759+
void clear() {
760+
cache.clear();
761+
}
762+
}
730763
}

tests/functional/request-scope/src/test/java/io/helidon/tests/functional/requestscope/TenantTest.java

-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import jakarta.ws.rs.client.WebTarget;
2727
import jakarta.ws.rs.core.Response;
2828
import jakarta.ws.rs.core.Response.Status;
29-
import org.junit.jupiter.api.Disabled;
3029
import org.junit.jupiter.api.Test;
3130

3231
import static org.hamcrest.CoreMatchers.is;
@@ -47,7 +46,6 @@ public void test() throws Exception {
4746
}
4847

4948
@Test
50-
@Disabled // issue #8813
5149
public void test2() throws Exception {
5250
asyncCalls(() -> baseTarget.path("test2").request()
5351
.header("x-tenant-id", "123").get(), null);

0 commit comments

Comments
 (0)