处理一些合并冲突

This commit is contained in:
super
2026-05-05 14:11:35 +08:00
parent 710b953120
commit 203937335d
19 changed files with 1075 additions and 198 deletions

View File

@@ -6,15 +6,21 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.time.Clock;
import java.time.ZoneId;
@Configuration
@Slf4j
public class SchedulingConfig {
private static final ZoneId BUSINESS_ZONE = ZoneId.of("Asia/Shanghai");
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(4);
scheduler.setThreadNamePrefix("aiimage-scheduling-");
scheduler.setClock(Clock.system(BUSINESS_ZONE));
scheduler.setWaitForTasksToCompleteOnShutdown(true);
scheduler.setAwaitTerminationSeconds(30);
scheduler.setErrorHandler(ex -> log.warn("[scheduling] task execution failed: {}", ex.getMessage(), ex));

View File

@@ -0,0 +1,78 @@
package com.nanri.aiimage.config;
import com.nanri.aiimage.common.exception.BusinessException;
import com.nanri.aiimage.modules.task.service.TaskDistributedLockService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Configuration
@RequiredArgsConstructor
public class TaskOperationLockConfig implements WebMvcConfigurer {
private final TaskDistributedLockService taskDistributedLockService;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TaskOperationLockInterceptor(taskDistributedLockService))
.addPathPatterns("/api/**");
}
@Slf4j
private static final class TaskOperationLockInterceptor implements HandlerInterceptor {
private static final Pattern TASK_PATH = Pattern.compile(".*/api/([^/]+)/tasks/(\\d+)(?:/.*)?$");
private static final Set<String> MUTATING_METHODS = Set.of("POST", "PUT", "PATCH", "DELETE");
private static final String LOCK_ATTRIBUTE = TaskOperationLockInterceptor.class.getName() + ".LOCK";
private final TaskDistributedLockService taskDistributedLockService;
private TaskOperationLockInterceptor(TaskDistributedLockService taskDistributedLockService) {
this.taskDistributedLockService = taskDistributedLockService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (!MUTATING_METHODS.contains(request.getMethod())) {
return true;
}
String uri = request.getRequestURI();
Matcher matcher = TASK_PATH.matcher(uri == null ? "" : uri);
if (!matcher.matches()) {
return true;
}
String moduleType = matcher.group(1).trim().toUpperCase(Locale.ROOT).replace('-', '_');
Long taskId = Long.valueOf(matcher.group(2));
TaskDistributedLockService.LockHandle lockHandle =
taskDistributedLockService.acquire(moduleType, taskId, TaskDistributedLockService.DEFAULT_WAIT_MILLIS);
if (lockHandle == null) {
log.info("[task-operation-lock] rejected busy task operation method={} uri={} moduleType={} taskId={}",
request.getMethod(), uri, moduleType, taskId);
throw new BusinessException(40902, "TASK_LOCK_BUSY");
}
request.setAttribute(LOCK_ATTRIBUTE, lockHandle);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
Object lockHandle = request.getAttribute(LOCK_ATTRIBUTE);
if (lockHandle instanceof TaskDistributedLockService.LockHandle handle) {
handle.close();
}
}
}
}