Skip to content

Commit

Permalink
Do not spawn useslss threads
Browse files Browse the repository at this point in the history
  • Loading branch information
Croway committed Jan 29, 2025
1 parent 1250d77 commit 2df89e2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
package org.apache.camel.component.platform.http.springboot;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
Expand All @@ -41,14 +40,15 @@
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

public class SpringBootPlatformHttpConsumer extends DefaultConsumer implements PlatformHttpConsumer, Suspendable, SuspendableService {

private static final Logger LOG = LoggerFactory.getLogger(SpringBootPlatformHttpConsumer.class);

private HttpBinding binding;
private final boolean handleWriteResponseError;
private Executor executor;
private CookieConfiguration cookieConfiguration;

public SpringBootPlatformHttpConsumer(PlatformHttpEndpoint endpoint, Processor processor) {
Expand All @@ -59,12 +59,6 @@ public SpringBootPlatformHttpConsumer(PlatformHttpEndpoint endpoint, Processor p
this.binding.setFileNameExtWhitelist(endpoint.getFileNameExtWhitelist());
this.binding.setUseReaderForPayload(!endpoint.isUseStreaming());
this.handleWriteResponseError = endpoint.isHandleWriteResponseError();
this.executor = Executors.newSingleThreadExecutor();
}

public SpringBootPlatformHttpConsumer(PlatformHttpEndpoint endpoint, Processor processor, Executor executor) {
this(endpoint, processor);
this.executor = executor;
}

/**
Expand All @@ -80,26 +74,29 @@ public PlatformHttpEndpoint getEndpoint() {
}

/**
* This method is invoked by Spring Boot when invoking Camel via platform-http
* This method is invoked by Spring Boot when invoking Camel via platform-http.
*
* The method is already running asynchronously via AsyncExecutionInterceptor.
*
* Returns an empty CompletableFuture as per documentation https://spring.io/guides/gs/async-method
*/
@ResponseBody
public CompletableFuture<Void> service(HttpServletRequest request, HttpServletResponse response) {
return CompletableFuture.runAsync(() -> {
LOG.trace("Service: {}", request);
LOG.trace("Service: {}", request);
try {
handleService(request, response);
} catch (Exception e) {
// do not leak exception back to caller
LOG.warn("Error handling request due to: {}", e.getMessage(), e);
try {
handleService(request, response);
} catch (Exception e) {
// do not leak exception back to caller
LOG.warn("Error handling request due to: {}", e.getMessage(), e);
try {
if (!response.isCommitted()) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
} catch (Exception e1) {
// ignore
if (!response.isCommitted()) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
} catch (Exception e1) {
// ignore
}
}, executor);
}
return CompletableFuture.completedFuture(null);
}

protected void handleService(HttpServletRequest request, HttpServletResponse response) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public SpringBootPlatformHttpEngine(int port, Executor executor) {
@Override
public PlatformHttpConsumer createConsumer(PlatformHttpEndpoint endpoint, Processor processor) {
ProxyFactory factory = new ProxyFactory();
factory.setTarget(new SpringBootPlatformHttpConsumer(endpoint, processor, executor));
factory.setTarget(new SpringBootPlatformHttpConsumer(endpoint, processor));

JdkRegexpMethodPointcut jdkRegexpMethodPointcut = new JdkRegexpMethodPointcut();
jdkRegexpMethodPointcut.setPattern("org.apache.camel.component.platform.http.springboot.SpringBootPlatformHttpConsumer.service");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
Expand Down Expand Up @@ -179,8 +186,18 @@ protected String getGetRouteId() {
public void testLoad() throws Exception {
waitUntilRouteIsStarted(1, getGetRouteId());

ExecutorService es = Executors.newFixedThreadPool(10);
List<CompletableFuture> tasks = new ArrayList();
for (int i = 0; i < 1_000; i++) {
Assertions.assertThat(restTemplate.getForEntity("/myget", String.class).getStatusCode().value()).isEqualTo(200);
tasks.add(CompletableFuture.runAsync(() ->
Assertions.assertThat(restTemplate.getForEntity("/myget", String.class)
.getStatusCode().value()).isEqualTo(200), es));
}
for (CompletableFuture<Void> task : tasks) {
task.get();
if (task.isCompletedExceptionally()) {
org.junit.jupiter.api.Assertions.fail("Exception thrown during execution, check logs");
}
}
}

Expand Down

0 comments on commit 2df89e2

Please sign in to comment.