Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache value of CDI.current() to improve performance on repeated invoc… #310

Merged
merged 1 commit into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.smallrye.context.jta.context.propagation;

import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand All @@ -24,6 +25,8 @@ public class JtaContextProvider implements ThreadContextProvider {
private volatile TransactionManager transactionManager;
// this allows us to cache null values
private volatile boolean transactionManagerNotAvailable;
// cached value indicating if CDI is not available, boolean is assigned on first call
private AtomicReference<Boolean> cdiNotAvailable = new AtomicReference<>(null);

@Override
public ThreadContextSnapshot currentContext(Map<String, String> props) {
Expand Down Expand Up @@ -176,18 +179,34 @@ public String getThreadContextType() {
/**
* Checks if CDI is available within the application by using {@code CDI.current()}.
* If an exception is thrown, it is suppressed and false is returns, otherwise true is returned.
* <p/>
* Uses {@code CDI.current()} in its first invocation; subsequent invocations use cached value as we presume the
* presence/absence state of CDI within application cannot change while the application executes. This should
* improve performance.
* <p/>
* NOTE: this has a potential downside if the CDI provider exists but the CDI container can change its state while user
* application executes. I.e. manually stopping the CDI container and then trying to use JTA context propagation
* will behave weirdly.
*
* @return true if CDI can be used, false otherwise
*/
private boolean isCdiUnavailable() {
Boolean cdiUnavailable = cdiNotAvailable.get();
if (cdiUnavailable != null) {
return cdiUnavailable;
}
if (transactionManager != null) {
//we looked this up from CDI, so we know it is fine
cdiNotAvailable.set(false);
return false;
}
try {
return CDI.current() == null;
boolean result = CDI.current() == null;
cdiNotAvailable.set(result);
return result;
} catch (IllegalStateException e) {
// no CDI provider found, CDI isn't available
cdiNotAvailable.set(true);
return true;
}
}
Expand Down
3 changes: 2 additions & 1 deletion tests/src/test/java/io/smallrye/context/ManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

import io.smallrye.context.impl.ThreadContextProviderPlan;
import io.smallrye.context.test.DefaultThreadContextProvider;
import io.smallrye.context.test.util.AbstractTest;

public class ManagerTest {
public class ManagerTest extends AbstractTest {

List<String> record = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@

import io.reactivex.observers.TestObserver;
import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.test.util.AbstractTest;
import rx.observers.AssertableSubscriber;

public class BackPressureExceptionTest {
public class BackPressureExceptionTest extends AbstractTest {

@BeforeClass
public static void before() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
import io.smallrye.context.SmallRyeThreadContext;
import io.smallrye.context.impl.Contextualized;
import io.smallrye.context.impl.ThreadContextProviderPlan;
import io.smallrye.context.test.util.AbstractTest;

public class CompletableFutureTest {
public class CompletableFutureTest extends AbstractTest {

private SmallRyeManagedExecutor managedExecutor;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import io.smallrye.context.CleanAutoCloseable;
import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.SmallRyeThreadContext;
import io.smallrye.context.test.util.AbstractTest;

public class CurrentThreadContextTest {
public class CurrentThreadContextTest extends AbstractTest {
@Test
public void testCurrentThreadContext() throws InterruptedException, ExecutionException {
MyContext ctx = new MyContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@
import com.arjuna.ats.jta.logging.jtaLogger;

import io.restassured.RestAssured;
import io.smallrye.context.test.util.AbstractTest;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;

public class FullStackTest {
public class FullStackTest extends AbstractTest {
private final class MyVertxJaxrsServer extends VertxJaxrsServer {
public Vertx getVertx() {
return vertx;
Expand Down
3 changes: 2 additions & 1 deletion tests/src/test/java/io/smallrye/context/test/JTATest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@

import io.smallrye.context.inject.TransactionServicesImpl;
import io.smallrye.context.test.jta.TransactionalService;
import io.smallrye.context.test.util.AbstractTest;

public class JTATest {
public class JTATest extends AbstractTest {
private static Weld weld;

@BeforeClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@

import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.SmallRyeThreadContext;
import io.smallrye.context.test.util.AbstractTest;

public class ManualPropagationMultipleRequestTest {
public class ManualPropagationMultipleRequestTest extends AbstractTest {

private static SmallRyeThreadContext threadContext;
private static SmallRyeThreadContext minimalThreadContext;
Expand Down
3 changes: 2 additions & 1 deletion tests/src/test/java/io/smallrye/context/test/MiscTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@

import io.smallrye.context.SmallRyeContextManager;
import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.test.util.AbstractTest;

public class MiscTest {
public class MiscTest extends AbstractTest {

@Test
public void testCFWrapping() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
import org.junit.Test;

import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.test.util.AbstractTest;
import rx.Emitter.BackpressureMode;
import rx.Observable;
import rx.Scheduler;
import rx.schedulers.Schedulers;

public class RxJava1MultipleRequestTest {
public class RxJava1MultipleRequestTest extends AbstractTest {

@BeforeClass
public static void init() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
import org.junit.Test;

import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.test.util.AbstractTest;
import rx.Completable;
import rx.Emitter.BackpressureMode;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;

public class RxJava1Test {
public class RxJava1Test extends AbstractTest {

@BeforeClass
public static void init() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;
import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.test.util.AbstractTest;

public class RxJava2Test {
public class RxJava2Test extends AbstractTest {

@BeforeClass
public static void init() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
import org.junit.Test;

import io.smallrye.context.test.JTAUtils;
import io.smallrye.context.test.util.AbstractTest;

public class CdiContextPropagatesTest {
public class CdiContextPropagatesTest extends AbstractTest {

private static Weld weld;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@
import io.smallrye.context.SmallRyeContextManagerProvider;
import io.smallrye.context.api.ManagedExecutorConfig;
import io.smallrye.context.impl.DefaultValues;
import io.smallrye.context.test.util.AbstractTest;

public class MultiClassloadingTest {
public class MultiClassloadingTest extends AbstractTest {

public static class AThreadContextPropagator implements ContextManagerExtension {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.smallrye.context.test.util;

import org.junit.BeforeClass;

import io.smallrye.context.SmallRyeContextManagerProvider;

/**
* A parent test which should be extended by all test classes in this module.
* <p/>
* This class defines {@code @BeforeClass} callback making sure each test starts with a clean
* {@code SmallryeContextManager} state. This is because {@code SmallRyeContextManagerProvider} keeps a map of
* SR Context Managers per class loader and since all tests run in a single class loader, any optimization efforts
* using caching may lead to issues.
*/
public abstract class AbstractTest {

@BeforeClass
public static void performContextManagerCleanup() {
SmallRyeContextManagerProvider.instance().releaseContextManager(SmallRyeContextManagerProvider.getManager());
}

}