From a69f9ef3839bbf759480a836f46a20809ccec402 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期一, 27 四月 2026 13:14:17 +0800
Subject: [PATCH] fix: prevent running auto tune jobs on apply failure

---
 src/main/java/com/zy/ai/service/impl/AutoTuneApplyServiceImpl.java |   30 +++++++++++++++++++++++-------
 1 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/main/java/com/zy/ai/service/impl/AutoTuneApplyServiceImpl.java b/src/main/java/com/zy/ai/service/impl/AutoTuneApplyServiceImpl.java
index f443517..a8a95e5 100644
--- a/src/main/java/com/zy/ai/service/impl/AutoTuneApplyServiceImpl.java
+++ b/src/main/java/com/zy/ai/service/impl/AutoTuneApplyServiceImpl.java
@@ -26,6 +26,8 @@
 import com.zy.core.enums.RedisKeyType;
 import com.zy.system.entity.Config;
 import com.zy.system.service.ConfigService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.PlatformTransactionManager;
@@ -42,10 +44,11 @@
 @Service("autoTuneApplyService")
 public class AutoTuneApplyServiceImpl implements AutoTuneApplyService {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(AutoTuneApplyServiceImpl.class);
     private static final String PROMPT_SCENE_CODE = "auto_tune_apply";
     private static final String DIRECTION_OUT = "OUT";
     private static final long APPLY_LOCK_SECONDS = 120L;
-    private static final String APPLY_LOCK_BUSY_REASON = "AI鑷姩璋冨弬姝e湪鎵ц锛岃绋嶅悗閲嶈瘯";
+    private static final String APPLY_LOCK_BUSY_REASON = "鐢宠璋冨弬閿佸け璐ワ紝閿佷笉鍙敤锛屽彲鑳藉凡鏈変换鍔℃垨 Redis 寮傚父";
 
     @Autowired
     private AiAutoTuneJobService aiAutoTuneJobService;
@@ -72,7 +75,6 @@
         boolean dryRun = Boolean.TRUE.equals(safeRequest.getDryRun());
         Date now = new Date();
         AiAutoTuneJob job = createJob(safeRequest, dryRun, now);
-        aiAutoTuneJobService.save(job);
 
         if (dryRun) {
             return applyDryRun(safeRequest, job, now);
@@ -109,7 +111,7 @@
         String lockKey = RedisKeyType.AI_AUTO_TUNE_APPLY_LOCK.key;
         String lockToken = UUID.randomUUID().toString();
         if (!redisUtil.trySetStringIfAbsent(lockKey, lockToken, APPLY_LOCK_SECONDS)) {
-            return rejectRealApplyForBusyLock(request, job, now);
+            return rejectRealApplyForUnavailableLock(request, job, now, lockKey);
         }
 
         try {
@@ -143,22 +145,29 @@
                 return buildResult(job, persistenceResult.getAuditChanges(), false);
             } catch (RuntimeException exception) {
                 markWriteFailure(validatedChanges, exception);
+                Date failureNow = new Date();
+                AiAutoTuneJob failureJob = createJob(request, false, failureNow);
                 ApplyPersistenceResult persistenceResult = persistApplyResultInTransaction(
-                        job,
+                        failureJob,
                         request,
                         validatedChanges,
                         false,
-                        now,
+                        failureNow,
                         false
                 );
-                return buildResult(job, persistenceResult.getAuditChanges(), false);
+                return buildResult(failureJob, persistenceResult.getAuditChanges(), false);
             }
         } finally {
             redisUtil.compareAndDelete(lockKey, lockToken);
         }
     }
 
-    private AutoTuneApplyResult rejectRealApplyForBusyLock(AutoTuneApplyRequest request, AiAutoTuneJob job, Date now) {
+    private AutoTuneApplyResult rejectRealApplyForUnavailableLock(AutoTuneApplyRequest request,
+                                                                  AiAutoTuneJob job,
+                                                                  Date now,
+                                                                  String lockKey) {
+        boolean lockKeyExists = redisUtil.hasKey(lockKey);
+        LOGGER.warn("鐢宠AI鑷姩璋冨弬 apply 閿佸け璐ワ紝lockKey={}, lockKeyExists={}", lockKey, lockKeyExists);
         List<ValidatedChange> validatedChanges = buildLockBusyChanges(request);
         ApplyPersistenceResult persistenceResult = persistApplyResultInTransaction(
                 job,
@@ -397,6 +406,7 @@
                                                      boolean dryRun,
                                                      Date now,
                                                      boolean writeTargets) {
+        saveJob(job);
         boolean refreshConfigCache = false;
         if (writeTargets) {
             refreshConfigCache = applyValidatedChanges(validatedChanges);
@@ -408,6 +418,12 @@
         return new ApplyPersistenceResult(auditChanges, refreshConfigCache);
     }
 
+    private void saveJob(AiAutoTuneJob job) {
+        if (!aiAutoTuneJobService.save(job)) {
+            throw new IllegalStateException("淇濆瓨璋冨弬浠诲姟澶辫触");
+        }
+    }
+
     private boolean applyValidatedChanges(List<ValidatedChange> validatedChanges) {
         boolean refreshConfigCache = false;
         for (ValidatedChange validatedChange : validatedChanges) {

--
Gitblit v1.9.1