diff --git a/apps/user-service/build.gradle b/apps/user-service/build.gradle index 23c23124..4c5cb671 100644 --- a/apps/user-service/build.gradle +++ b/apps/user-service/build.gradle @@ -63,6 +63,7 @@ dependencies { implementation "io.micrometer:micrometer-tracing" implementation 'io.micrometer:micrometer-registry-prometheus' implementation "org.springframework.boot:spring-boot-starter-actuator" + implementation "io.micrometer:context-propagation" // Lombok compileOnly 'org.projectlombok:lombok:1.18.30' diff --git a/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java b/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java index 348058ee..9cd5933b 100644 --- a/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java +++ b/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java @@ -1,7 +1,5 @@ package site.icebang.domain.workflow.controller; -import java.util.concurrent.CompletableFuture; - import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -31,7 +29,7 @@ public ApiResponse> getWorkflowList( @PostMapping("/{workflowId}/run") public ResponseEntity runWorkflow(@PathVariable Long workflowId) { // HTTP 요청/응답 스레드를 블로킹하지 않도록 비동기 실행 - CompletableFuture.runAsync(() -> workflowExecutionService.executeWorkflow(workflowId)); + workflowExecutionService.executeWorkflow(workflowId); return ResponseEntity.accepted().build(); } } diff --git a/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowExecutionService.java b/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowExecutionService.java index 60da5863..1d25b856 100644 --- a/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowExecutionService.java +++ b/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowExecutionService.java @@ -5,6 +5,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -43,6 +44,7 @@ public class WorkflowExecutionService { private final List bodyBuilders; @Transactional + @Async("traceExecutor") public void executeWorkflow(Long workflowId) { log.info("========== 워크플로우 실행 시작: WorkflowId={} ==========", workflowId); WorkflowRun workflowRun = WorkflowRun.start(workflowId); diff --git a/apps/user-service/src/main/java/site/icebang/global/config/asnyc/AsyncConfig.java b/apps/user-service/src/main/java/site/icebang/global/config/asnyc/AsyncConfig.java new file mode 100644 index 00000000..8d664028 --- /dev/null +++ b/apps/user-service/src/main/java/site/icebang/global/config/asnyc/AsyncConfig.java @@ -0,0 +1,24 @@ +package site.icebang.global.config.asnyc; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.support.ContextPropagatingTaskDecorator; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig { + + @Bean("traceExecutor") + public ThreadPoolTaskExecutor traceExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(10); + executor.setMaxPoolSize(50); + executor.setQueueCapacity(100); + executor.setTaskDecorator(new ContextPropagatingTaskDecorator()); // 필수 + executor.setThreadNamePrefix("trace-"); + executor.initialize(); + return executor; + } +}