FINERACT-2449: Replace unbounded SimpleAsyncTaskExecutor with ThreadPoolTaskExecutor#5432
Conversation
|
I think there is a need to address this... but (having best practices in mind): let's first have a look here https://docs.spring.io/spring-boot/reference/features/task-execution-and-scheduling.html ... there are already (auto) configuration properties available, so why invent our own and create more Java configuration when they are not really necessary. I only cross-read that documentation quickly, but I think everything that is done here can be achieved with adding the proper "spring" prefixed properties to application.properties (with environment variable placeholders, sure); I think no extra/custom Java configuration would be needed. |
|
Hi @vidakovic, thanks for the review. I investigated using 1. Synchronous by default
Unless 2. Security context propagation Because of this, a properties-only solution isn't sufficient. That said, I'm happy to Does that approach work for you? |
Sounds right to me. |
|
I learned again something... Thanks for digging this up. Suggestion sound good, let's then move on |
773a82c to
4741fbc
Compare
|
@vidakovic @adamsaghy Thank you for the feedbacks! |
fineract-provider/src/test/resources/application-test.properties
Outdated
Show resolved
Hide resolved
4741fbc to
edb6bea
Compare
|
@adamsaghy This test failure seems unrelated to my changes |
Description
This PR addresses FINERACT-2449.
Background
The current
SimpleAsyncTaskExecutorcreates a new thread for every asynchronous event. While effective for light loads, this unbounded behavior poses a risk of thread exhaustion (OutOfMemoryError: unable to create native thread) under high-concurrency scenarios.Motivation
Relying on an unbounded executor is contrary to Spring Boot best practices for production-grade financial systems. This change proactively addresses the risk before it manifests in production.
Solution
As discussed with @vidakovic, a properties-only approach was insufficient due to security context requirements and synchronous defaults. This solution uses the standard Spring Boot Builder to honor
spring.task.executionproperties while enforcing Fineract-specific safety.SpringConfig.javaSimpleAsyncTaskExecutorwithThreadPoolTaskExecutorviaThreadPoolTaskExecutorBuilder. Implemented "Smart Defaults" (CPU-aware) if properties are unset. AddedCallerRunsPolicyfor zero data loss.SpringConfigTest.javaApplicationContextRunnerand concurrency latches to prove bounded behavior, backpressure, and mode compatibility.application.propertiesfineract.task-executorproperties in favor of standardspring.task.execution.pool.*.Testing
The updated
SpringConfigTest.javasuite provides the following proofs:CallerRunsPolicyforces the main thread to execute tasks when the pool is saturated.ApplicationContextRunnerto verify the Event Executor bean is correctly configured inREAD,WRITE,BATCH_WORKER, andBATCH_MANAGERmodes.maxPoolSizeis automatically adjusted if user configuration is invalid (e.g., Core > Max).Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!