Configure Virtual Threads support in Reactor
This commit configures the virtual threads support in Reactor Core for Schedulers if: * the current JDK is 21 or higher * the current environment enables this globally with the `"spring.threads.virtual.enabled"` property. This needs to happen early in the application startup process, as this feature is detected statically when the first schedulers call is made. As a result, this is being done with an environment post processor and not with an auto-configuration class. Closes gh-36302
This commit is contained in:
parent
1798c561f4
commit
d46a58f0f6
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,31 +18,34 @@ package org.springframework.boot.reactor;
|
|||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.boot.system.JavaVersion;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link EnvironmentPostProcessor} to enable the Reactor Debug Agent if available.
|
||||
* {@link EnvironmentPostProcessor} to enable the Reactor global features as early as
|
||||
* possible in the startup process.
|
||||
* <p>
|
||||
* The debug agent is enabled by default, unless the
|
||||
* {@code "spring.reactor.debug-agent.enabled"} configuration property is set to false. We
|
||||
* are using here an {@link EnvironmentPostProcessor} instead of an auto-configuration
|
||||
* class to enable the agent as soon as possible during the startup process.
|
||||
* If the "reactor-tools" dependency is available, the debug agent is enabled by default,
|
||||
* unless the {@code "spring.reactor.debug-agent.enabled"} configuration property is set
|
||||
* to false.
|
||||
* <p>
|
||||
* If the {@code "spring.threads.virtual.enabled"} property is enabled and the current JVM
|
||||
* is 21 or later, then the Reactor System property is set to configure the Bounded
|
||||
* Elastic Scheduler to use Virtual Threads globally.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.2.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public class DebugAgentEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||
public class ReactorEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||
|
||||
private static final String REACTOR_DEBUGAGENT_CLASS = "reactor.tools.agent.ReactorDebugAgent";
|
||||
|
||||
private static final String DEBUGAGENT_ENABLED_CONFIG_KEY = "spring.reactor.debug-agent.enabled";
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
if (ClassUtils.isPresent(REACTOR_DEBUGAGENT_CLASS, null)) {
|
||||
Boolean agentEnabled = environment.getProperty(DEBUGAGENT_ENABLED_CONFIG_KEY, Boolean.class);
|
||||
Boolean agentEnabled = environment.getProperty("spring.reactor.debug-agent.enabled", Boolean.class);
|
||||
if (agentEnabled != Boolean.FALSE) {
|
||||
try {
|
||||
Class<?> debugAgent = Class.forName(REACTOR_DEBUGAGENT_CLASS);
|
||||
|
@ -53,6 +56,10 @@ public class DebugAgentEnvironmentPostProcessor implements EnvironmentPostProces
|
|||
}
|
||||
}
|
||||
}
|
||||
if (environment.getProperty("spring.threads.virtual.enabled", boolean.class, false)
|
||||
&& JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.TWENTY_ONE)) {
|
||||
System.setProperty("reactor.schedulers.defaultBoundedElasticOnVirtualThreads", "true");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
|
@ -491,7 +491,7 @@
|
|||
{
|
||||
"name": "spring.reactor.debug-agent.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"sourceType": "org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor",
|
||||
"sourceType": "org.springframework.boot.reactor.ReactorEnvironmentPostProcessor",
|
||||
"description": "Whether the Reactor Debug Agent should be enabled when reactor-tools is present.",
|
||||
"defaultValue": true
|
||||
},
|
||||
|
|
|
@ -57,7 +57,7 @@ org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\
|
|||
org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,\
|
||||
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
|
||||
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
|
||||
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor
|
||||
org.springframework.boot.reactor.ReactorEnvironmentPostProcessor
|
||||
|
||||
# Failure Analyzers
|
||||
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
||||
|
|
|
@ -22,7 +22,7 @@ import reactor.core.publisher.Flux;
|
|||
* Utility class that should be instrumented by the reactor debug agent.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @see DebugAgentEnvironmentPostProcessorTests
|
||||
* @see ReactorEnvironmentPostProcessorTests
|
||||
*/
|
||||
class InstrumentedFluxProvider {
|
||||
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
|
||||
package org.springframework.boot.reactor;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import reactor.core.Scannable;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
|
@ -27,17 +29,18 @@ import org.springframework.mock.env.MockEnvironment;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DebugAgentEnvironmentPostProcessor}.
|
||||
* Tests for {@link ReactorEnvironmentPostProcessor}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@Disabled("We need the not-yet-released reactor-tools 3.4.11 for JDK 17 compatibility")
|
||||
@ClassPathOverrides("io.projectreactor:reactor-tools:3.4.11")
|
||||
class DebugAgentEnvironmentPostProcessorTests {
|
||||
|
||||
@ClassPathOverrides("io.projectreactor:reactor-tools:3.5.9")
|
||||
class ReactorEnvironmentPostProcessorTests {
|
||||
|
||||
static {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
DebugAgentEnvironmentPostProcessor postProcessor = new DebugAgentEnvironmentPostProcessor();
|
||||
environment.setProperty("spring.threads.virtual.enabled", "true");
|
||||
ReactorEnvironmentPostProcessor postProcessor = new ReactorEnvironmentPostProcessor();
|
||||
postProcessor.postProcessEnvironment(environment, null);
|
||||
}
|
||||
|
||||
|
@ -49,4 +52,21 @@ class DebugAgentEnvironmentPostProcessorTests {
|
|||
.startsWith("Flux.just ⇢ at org.springframework.boot.reactor.InstrumentedFluxProvider.newFluxJust");
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForJreRange(max = JRE.JAVA_20)
|
||||
void shouldNotEnableVirtualThreads() {
|
||||
assertThat(System.getProperty("reactor.schedulers.defaultBoundedElasticOnVirtualThreads")).isNotEqualTo("true");
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForJreRange(min = JRE.JAVA_21)
|
||||
void shouldEnableVirtualThreads() {
|
||||
assertThat(System.getProperty("reactor.schedulers.defaultBoundedElasticOnVirtualThreads")).isEqualTo("true");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
System.setProperty("reactor.schedulers.defaultBoundedElasticOnVirtualThreads", "false");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue