Merge branch 'hotfix-async-tenantcontext' into 'main'

hotfix tenant context not available in async calls

See merge request fforesight/tenant-commons!15
This commit is contained in:
Maverick Studer 2024-07-01 10:14:21 +02:00
commit 183ae05ec3
2 changed files with 59 additions and 0 deletions

View File

@ -0,0 +1,23 @@
package com.knecon.fforesight.tenantcommons.task;
import static org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME;
import static org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor.DEFAULT_TASK_EXECUTOR_BEAN_NAME;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.task.TaskExecutorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@ConditionalOnClass(ThreadPoolTaskExecutor.class)
@Configuration
public class ApplicationTaskExecutorBeanConfig {
@Lazy
@Bean(name = {APPLICATION_TASK_EXECUTOR_BEAN_NAME, DEFAULT_TASK_EXECUTOR_BEAN_NAME})
public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {
return builder.build();
}
}

View File

@ -1,11 +1,47 @@
package com.knecon.fforesight.tenantcommons.task;
import java.util.function.Supplier;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.task.TaskExecutorCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableAsync;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
@Configuration(proxyBeanMethods = false)
@PropertySource("classpath:tenant-commons-task.properties")
@ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "false")
@EnableAsync
@Slf4j
public class TaskExecutionConfiguration {
private final static Supplier<KneconTaskDecorator> IDENTITY_KNECON_TASK_DECORATOR_SUPPLIER = () -> runna -> runna;
@Value("${spring.task.execution.pool.warnPercentageThreshold:80}")
private int executorWarnPercentageThreshold;
@Bean
public TaskExecutorCustomizer taskExecutorCustomizer(ObjectProvider<KneconTaskDecorator> taskDecorator) {
return taskExecutor -> {
taskExecutor.setTaskDecorator((KneconTaskDecorator) runnable -> {
val taskDecoratorUsed = taskDecorator.getIfUnique(IDENTITY_KNECON_TASK_DECORATOR_SUPPLIER);
val decoratedRunnable = taskDecoratorUsed.decorate(runnable);
val actualQueueSize = taskExecutor.getQueueSize() + 1;
val queueOccupancyPercentage = actualQueueSize * 100.f / taskExecutor.getMaxPoolSize();
if (queueOccupancyPercentage >= executorWarnPercentageThreshold) {
log.warn("Executor pool [ " + taskExecutor + " ] queue size reached " + actualQueueSize + "/" + taskExecutor.getMaxPoolSize() +
" entries awaiting execution triggering the warn level set for " + executorWarnPercentageThreshold +"% occupancy.");
}
return decoratedRunnable;
});
};
}
}