Forráskód Böngészése

feat(汇安融): 订单轮询间隔 60 秒 → 10 秒(用户裁定)

退款/支付状态收敛的可见延迟 = 单笔查询游标(首档 30 秒)+ 调度器捞取间隔。
原 60 秒间隔实测让「退款点完」到「状态翻页」要等约 1~2 分钟(用户以当日
多笔退款联调单点名)。2026-10-09 裁定收紧到 10 秒。

- HarOrderPollScheduler#pollPendingOrders:fixedDelay / initialDelay 均 60s → 10s
- 只改「发货」节奏:单笔订单两次查询的间距由各自的 next_query_time 游标控制
  (30s 起步退避),对上游的查询密度不变,只减少「已到期却还没被捞走」的空等
- retryFailedCallbacks 保持 60s / 75s 不动(本次裁定未涉及回调重试节奏)
- HarOrderPollSchedulerTest 新增两条钉住用例(先红后绿):poll = 10s、
  retry = 60s(该文件此前没有任何调度间隔断言,改回大值曾可静默过)

测试:聚焦 18/18 绿;全量 1270/0/0/0(见交付说明补记 ③)。
alphaH 6 napja
szülő
commit
f2ef6b13be

+ 8 - 1
java/src/main/java/com/payment/platform/module/payment/har/scheduler/HarOrderPollScheduler.java

@@ -35,7 +35,14 @@ public class HarOrderPollScheduler {
         this.callbackService = callbackService;
     }
 
-    @Scheduled(fixedDelay = 60 * 1000, initialDelay = 60 * 1000)
+    /**
+     * 轮询间隔 10 秒(2026-10-09 用户裁定,原 60 秒 —— 退款后状态翻页实测要等约 60 秒)。
+     *
+     * <p>调度器只是「发货」节奏:单笔订单两次查询之间的间距由各自的 {@code next_query_time}
+     * 游标控制(30s 起步退避),收紧本间隔**不会**增加对上游的查询密度,只减少
+     * 「已到期却还没被捞走」的空等。首轮启动延迟同步收 10 秒。
+     */
+    @Scheduled(fixedDelay = 10 * 1000, initialDelay = 10 * 1000)
     public void pollPendingOrders() {
         if (!harProperties.isEnabled()) {
             return;

+ 35 - 0
java/src/test/java/com/payment/platform/module/payment/har/scheduler/HarOrderPollSchedulerTest.java

@@ -10,10 +10,13 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.scheduling.annotation.Scheduled;
 
 import java.util.List;
 
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.*;
 
@@ -131,4 +134,36 @@ class HarOrderPollSchedulerTest {
 
         assertDoesNotThrow(scheduler::retryFailedCallbacks);
     }
+
+    // ==================== 调度节奏(2026-10-09 用户裁定) ====================
+
+    /**
+     * 轮询间隔是**用户可感知的延迟承诺**:支付/退款状态从上游发生变化到本地可见的等待
+     * ≈ 单笔查询游标(首档 30 秒)+ 本间隔(实测痛点:退款点完等了约 60 秒状态才翻)。
+     * 2026-10-09 用户裁定从 60 秒收紧到 10 秒 —— 改回大值会静默拉长等待,
+     * 套件除本用例不会有任何红点。
+     */
+    @Test
+    void poll_scheduledEveryTenSeconds() throws Exception {
+        Scheduled scheduled = HarOrderPollScheduler.class
+                .getMethod("pollPendingOrders").getAnnotation(Scheduled.class);
+        assertNotNull(scheduled, "pollPendingOrders 必须挂 @Scheduled —— 摘掉它轮询就整个停了");
+        assertEquals(10 * 1000, scheduled.fixedDelay(),
+                "轮询间隔必须是 10 秒(2026-10-09 用户裁定,原 60 秒)");
+        assertEquals(10 * 1000, scheduled.initialDelay(),
+                "首轮启动延迟同步收 10 秒(原 60 秒)—— 重启后的第一笔也不该再等 60 秒");
+    }
+
+    /**
+     * 2026-10-09 的裁定**只动回调重试上限**(8→3,见 {@code HarProperties} 与
+     * har-callback-retry.sql):重试节奏仍是每分钟一轮。别顺手改这一条 ——
+     * 重试腿打的是商户地址,节奏与上限是两回事。
+     */
+    @Test
+    void retryCallbacks_scheduledEverySixtySeconds() throws Exception {
+        Scheduled scheduled = HarOrderPollScheduler.class
+                .getMethod("retryFailedCallbacks").getAnnotation(Scheduled.class);
+        assertNotNull(scheduled, "retryFailedCallbacks 必须挂 @Scheduled");
+        assertEquals(60 * 1000, scheduled.fixedDelay(), "回调重试节奏未在本次裁定内,保持每分钟一轮");
+    }
 }