diff --git a/app/.env b/app/.env index 517a315..63f4056 100644 --- a/app/.env +++ b/app/.env @@ -13,8 +13,8 @@ client_name=ShuFuAI # java_api_base=http://47.111.163.154:18080 -# java_api_base=http://127.0.0.1:18080 -java_api_base=http://8.136.19.173:18080 +java_api_base=http://127.0.0.1:18080 +# java_api_base=http://8.136.19.173:18080 # java_api_base=http://121.196.149.225:18080 diff --git a/app/amazon/__pycache__/approve.cpython-312.pyc b/app/amazon/__pycache__/approve.cpython-312.pyc index 859dd8c..d4bc9b6 100644 Binary files a/app/amazon/__pycache__/approve.cpython-312.pyc and b/app/amazon/__pycache__/approve.cpython-312.pyc differ diff --git a/app/amazon/__pycache__/asin_status.cpython-312.pyc b/app/amazon/__pycache__/asin_status.cpython-312.pyc new file mode 100644 index 0000000..1224c5c Binary files /dev/null and b/app/amazon/__pycache__/asin_status.cpython-312.pyc differ diff --git a/app/amazon/__pycache__/detail_spider.cpython-312.pyc b/app/amazon/__pycache__/detail_spider.cpython-312.pyc new file mode 100644 index 0000000..a646c09 Binary files /dev/null and b/app/amazon/__pycache__/detail_spider.cpython-312.pyc differ diff --git a/app/amazon/__pycache__/main.cpython-312.pyc b/app/amazon/__pycache__/main.cpython-312.pyc index a92e3b5..d1560d0 100644 Binary files a/app/amazon/__pycache__/main.cpython-312.pyc and b/app/amazon/__pycache__/main.cpython-312.pyc differ diff --git a/app/amazon/__pycache__/match_action.cpython-312.pyc b/app/amazon/__pycache__/match_action.cpython-312.pyc index b049682..da45664 100644 Binary files a/app/amazon/__pycache__/match_action.cpython-312.pyc and b/app/amazon/__pycache__/match_action.cpython-312.pyc differ diff --git a/app/amazon/__pycache__/price_match.cpython-312.pyc b/app/amazon/__pycache__/price_match.cpython-312.pyc index b3bad90..ec269dd 100644 Binary files a/app/amazon/__pycache__/price_match.cpython-312.pyc and b/app/amazon/__pycache__/price_match.cpython-312.pyc differ diff --git a/app/amazon/detail_spider.py b/app/amazon/detail_spider.py index 0558bbb..276c1fe 100644 --- a/app/amazon/detail_spider.py +++ b/app/amazon/detail_spider.py @@ -390,19 +390,20 @@ class SpiderTask: runing_task[task_id]["status"] = "failed" runing_task[task_id]["error"] = str(e) - def post_result(self, task_id: int, chunkIndex:int,chunkTotal: int, asin: str, error:str="", - item_data:dict={}, - is_done: bool = False): + def post_result(self, task_id: int, chunkIndex:int,chunkTotal: int, asin: str, error:str="", + item_data:dict={}, + is_done: bool = False): """回传处理结果到API """ url = f"{DELETE_BRAND_API_BASE}/api/appearance-patent/tasks/{task_id}/result" - payload ={ - "submissionId": f"{int(time.time())}", - "chunkIndex": chunkIndex, - "chunkTotal": chunkTotal, - "error": error, + submission_id = f"appearance-patent:{task_id}" + payload ={ + "submissionId": submission_id, + "chunkIndex": chunkIndex, + "chunkTotal": chunkTotal, + "error": error, "items": [ item_data ], @@ -410,8 +411,9 @@ class SpiderTask: } max_retries = 3 - for retry in range(max_retries): - try: + for retry in range(max_retries): + try: + request_timeout = 300 if is_done else 30 print("================【详情采集】=====================") self.log(f"尝试回传结果 (第 {retry + 1}/{max_retries} 次)") self.log(f"回传URL: {url}") @@ -420,7 +422,7 @@ class SpiderTask: url, json=payload, headers={"Content-Type": "application/json"}, - timeout=30, + timeout=request_timeout, verify=False ) self.log(f"回传结果: {response.text}") @@ -6904,4 +6906,4 @@ if __name__ == '__main__': }, "code": None } - spide.process_task(task_data) \ No newline at end of file + spide.process_task(task_data) diff --git a/backend-java/jstack-6488.txt b/backend-java/jstack-6488.txt new file mode 100644 index 0000000..f64239b --- /dev/null +++ b/backend-java/jstack-6488.txt @@ -0,0 +1,1056 @@ +2026-04-27 09:31:53 +Full thread dump Java HotSpot(TM) 64-Bit Server VM (21.0.9+7-LTS-338 mixed mode, sharing): + +Threads class SMR info: +_java_thread_list=0x00000206f5796f90, length=60, elements={ +0x00000206ef866420, 0x00000206ef868e90, 0x00000206ef86cf00, 0x00000206ef86ddf0, +0x00000206ef870990, 0x00000206ef87b540, 0x00000206ef881950, 0x00000206ef883800, +0x00000206f424c120, 0x00000206f4256ee0, 0x00000206f8610410, 0x00000206f54b87d0, +0x00000206f5302900, 0x00000206fae021d0, 0x00000206fa48d240, 0x00000206fa48a450, +0x00000206fa48cbb0, 0x00000206fa48c520, 0x00000206fb996340, 0x00000206fb997d80, +0x00000206fb998410, 0x00000206fb9976f0, 0x00000206fb994f90, 0x00000206fb9969d0, +0x00000206fb998aa0, 0x00000206fb995620, 0x00000206fb997060, 0x00000206fb999130, +0x00000206fb995cb0, 0x00000206fb99b890, 0x00000206fb9997c0, 0x00000206fb99c5b0, +0x00000206fb99bf20, 0x00000206fb99b200, 0x00000206fb999e50, 0x00000206fb99a4e0, +0x00000206fb99ab70, 0x00000206f613bc10, 0x00000206f613aef0, 0x00000206f613dce0, +0x00000206f613b580, 0x00000206f613f090, 0x00000206f613ea00, 0x00000206f613c2a0, +0x00000206f613c930, 0x00000206f6140440, 0x00000206f613fdb0, 0x00000206f6140ad0, +0x00000206f6141e80, 0x00000206f6141160, 0x00000206fbd56be0, 0x00000206fbd56550, +0x00000206fbd54b10, 0x00000206fbd58620, 0x00000206fbd59340, 0x00000206ff0af860, +0x00000206ff0b2650, 0x00000206ff0b1fc0, 0x00000206ff0b2ce0, 0x00000206ff0b3370 +} + +"Reference Handler" #9 [27888] daemon prio=10 os_prio=2 cpu=0.00ms elapsed=2043.37s tid=0x00000206ef866420 nid=27888 waiting on condition [0x000000a9555ff000] + java.lang.Thread.State: RUNNABLE + at java.lang.ref.Reference.waitForReferencePendingList(java.base@21.0.9/Native Method) + at java.lang.ref.Reference.processPendingReferences(java.base@21.0.9/Reference.java:246) + at java.lang.ref.Reference$ReferenceHandler.run(java.base@21.0.9/Reference.java:208) + +"Finalizer" #10 [3824] daemon prio=8 os_prio=1 cpu=0.00ms elapsed=2043.37s tid=0x00000206ef868e90 nid=3824 in Object.wait() [0x000000a9556ff000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait0(java.base@21.0.9/Native Method) + - waiting on <0x000000068c286d88> (a java.lang.ref.NativeReferenceQueue$Lock) + at java.lang.Object.wait(java.base@21.0.9/Object.java:366) + at java.lang.Object.wait(java.base@21.0.9/Object.java:339) + at java.lang.ref.NativeReferenceQueue.await(java.base@21.0.9/NativeReferenceQueue.java:48) + at java.lang.ref.ReferenceQueue.remove0(java.base@21.0.9/ReferenceQueue.java:158) + at java.lang.ref.NativeReferenceQueue.remove(java.base@21.0.9/NativeReferenceQueue.java:89) + - locked <0x000000068c286d88> (a java.lang.ref.NativeReferenceQueue$Lock) + at java.lang.ref.Finalizer$FinalizerThread.run(java.base@21.0.9/Finalizer.java:173) + +"Signal Dispatcher" #11 [36016] daemon prio=9 os_prio=2 cpu=0.00ms elapsed=2043.37s tid=0x00000206ef86cf00 nid=36016 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Attach Listener" #12 [32968] daemon prio=5 os_prio=2 cpu=0.00ms elapsed=2043.37s tid=0x00000206ef86ddf0 nid=32968 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Service Thread" #13 [31112] daemon prio=9 os_prio=0 cpu=31.25ms elapsed=2043.37s tid=0x00000206ef870990 nid=31112 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Monitor Deflation Thread" #14 [34356] daemon prio=9 os_prio=0 cpu=109.38ms elapsed=2043.37s tid=0x00000206ef87b540 nid=34356 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"C2 CompilerThread0" #15 [33528] daemon prio=9 os_prio=2 cpu=9781.25ms elapsed=2043.37s tid=0x00000206ef881950 nid=33528 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + No compile task + +"C1 CompilerThread0" #23 [34520] daemon prio=9 os_prio=2 cpu=2015.62ms elapsed=2043.37s tid=0x00000206ef883800 nid=34520 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + No compile task + +"Notification Thread" #27 [30388] daemon prio=9 os_prio=0 cpu=15.62ms elapsed=2043.32s tid=0x00000206f424c120 nid=30388 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Common-Cleaner" #28 [13868] daemon prio=8 os_prio=1 cpu=0.00ms elapsed=2043.31s tid=0x00000206f4256ee0 nid=13868 waiting on condition [0x000000a955fff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068c2871c8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1852) + at java.lang.ref.ReferenceQueue.await(java.base@21.0.9/ReferenceQueue.java:71) + at java.lang.ref.ReferenceQueue.remove0(java.base@21.0.9/ReferenceQueue.java:143) + at java.lang.ref.ReferenceQueue.remove(java.base@21.0.9/ReferenceQueue.java:218) + at jdk.internal.ref.CleanerImpl.run(java.base@21.0.9/CleanerImpl.java:140) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + at jdk.internal.misc.InnocuousThread.run(java.base@21.0.9/InnocuousThread.java:186) + +"AsyncAppender-Worker-DefaultAppender" #48 [29512] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=2038.73s tid=0x00000206f8610410 nid=29512 waiting on condition [0x000000a956eff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068db9c8a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.ArrayBlockingQueue.take(java.base@21.0.9/ArrayBlockingQueue.java:420) + at org.apache.rocketmq.logging.ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:298) + +"Catalina-utility-1" #49 [34028] prio=1 os_prio=-2 cpu=640.62ms elapsed=2037.71s tid=0x00000206f54b87d0 nid=34028 waiting on condition [0x000000a9578fe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068dbb6988> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1177) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"Catalina-utility-2" #50 [32756] prio=1 os_prio=-2 cpu=625.00ms elapsed=2037.71s tid=0x00000206f5302900 nid=32756 waiting on condition [0x000000a9579ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068dbb6988> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"container-0" #51 [20256] prio=5 os_prio=0 cpu=0.00ms elapsed=2037.70s tid=0x00000206fae021d0 nid=20256 waiting on condition [0x000000a957aff000] + java.lang.Thread.State: TIMED_WAITING (sleeping) + at java.lang.Thread.sleep0(java.base@21.0.9/Native Method) + at java.lang.Thread.sleep(java.base@21.0.9/Thread.java:509) + at org.apache.catalina.core.StandardServer.await(StandardServer.java:520) + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:219) + +"Jndi-Dns-address-change-listener" #52 [7160] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=2037.51s tid=0x00000206fa48d240 nid=7160 runnable [0x000000a957bff000] + java.lang.Thread.State: RUNNABLE + at sun.net.dns.ResolverConfigurationImpl.notifyAddrChange0(java.base@21.0.9/Native Method) + at sun.net.dns.ResolverConfigurationImpl$AddressChangeListener.run(java.base@21.0.9/ResolverConfigurationImpl.java:179) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + at jdk.internal.misc.InnocuousThread.run(java.base@21.0.9/InnocuousThread.java:186) + +"lettuce-timer-3-1" #53 [31324] daemon prio=5 os_prio=0 cpu=578.12ms elapsed=2037.40s tid=0x00000206fa48a450 nid=31324 waiting on condition [0x000000a957cfe000] + java.lang.Thread.State: TIMED_WAITING (sleeping) + at java.lang.Thread.sleep0(java.base@21.0.9/Native Method) + at java.lang.Thread.sleep(java.base@21.0.9/Thread.java:509) + at io.netty.util.HashedWheelTimer$Worker.waitForNextTick(HashedWheelTimer.java:598) + at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:494) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"mysql-cj-abandoned-connection-cleanup" #54 [6776] daemon prio=5 os_prio=0 cpu=46.88ms elapsed=2036.99s tid=0x00000206fa48cbb0 nid=6776 waiting on condition [0x000000a957dff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068d7eebc8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1852) + at java.lang.ref.ReferenceQueue.await(java.base@21.0.9/ReferenceQueue.java:71) + at java.lang.ref.ReferenceQueue.remove0(java.base@21.0.9/ReferenceQueue.java:143) + at java.lang.ref.ReferenceQueue.remove(java.base@21.0.9/ReferenceQueue.java:218) + at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:93) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1144) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"MQClientFactoryScheduledThread" #56 [27804] prio=5 os_prio=0 cpu=62.50ms elapsed=2034.19s tid=0x00000206fa48c520 nid=27804 waiting on condition [0x000000a957eff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb00c98> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"NettyEventExecutor" #57 [28596] prio=5 os_prio=0 cpu=31.25ms elapsed=2034.19s tid=0x00000206fb996340 nid=28596 waiting on condition [0x000000a957fff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eafa238> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.LinkedBlockingQueue.poll(java.base@21.0.9/LinkedBlockingQueue.java:460) + at org.apache.rocketmq.remoting.netty.NettyRemotingAbstract$NettyEventExecutor.run(NettyRemotingAbstract.java:701) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"ClientHouseKeepingService" #55 [13476] prio=5 os_prio=0 cpu=796.88ms elapsed=2034.19s tid=0x00000206fb997d80 nid=13476 waiting on condition [0x000000a9580ff000] + java.lang.Thread.State: TIMED_WAITING (sleeping) + at java.lang.Thread.sleep0(java.base@21.0.9/Native Method) + at java.lang.Thread.sleep(java.base@21.0.9/Thread.java:509) + at io.netty.util.HashedWheelTimer$Worker.waitForNextTick(HashedWheelTimer.java:598) + at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:494) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"PullMessageService" #58 [37592] prio=5 os_prio=0 cpu=0.00ms elapsed=2034.18s tid=0x00000206fb998410 nid=37592 waiting on condition [0x000000a9581fe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb14bd8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.rocketmq.client.impl.consumer.PullMessageService.run(PullMessageService.java:131) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"RebalanceService" #59 [5336] prio=5 os_prio=0 cpu=0.00ms elapsed=2034.18s tid=0x00000206fb9976f0 nid=5336 waiting on condition [0x000000a9582ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb1b618> (a org.apache.rocketmq.common.CountDownLatch2$Sync) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@21.0.9/AbstractQueuedSynchronizer.java:756) + at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1126) + at org.apache.rocketmq.common.CountDownLatch2.await(CountDownLatch2.java:114) + at org.apache.rocketmq.common.ServiceThread.waitForRunning(ServiceThread.java:117) + at org.apache.rocketmq.client.impl.consumer.RebalanceService.run(RebalanceService.java:45) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"LatencyFaultToleranceScheduledThread" #60 [34044] prio=5 os_prio=0 cpu=343.75ms elapsed=2034.18s tid=0x00000206fb994f90 nid=34044 waiting on condition [0x000000a9583ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb22078> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"RequestHouseKeepingService1" #61 [36360] prio=5 os_prio=0 cpu=15.62ms elapsed=2034.18s tid=0x00000206fb9969d0 nid=36360 waiting on condition [0x000000a9584fe000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb28ad8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"LatencyFaultToleranceScheduledThread" #62 [36976] prio=5 os_prio=0 cpu=15.62ms elapsed=2034.18s tid=0x00000206fb998aa0 nid=36976 waiting on condition [0x000000a9585ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068e266628> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"Client_192.168.9.14@6488#167351209475700_GuardForSyncSend" #63 [33984] prio=5 os_prio=0 cpu=4125.00ms elapsed=2034.18s tid=0x00000206fb995620 nid=33984 waiting on condition [0x000000a9586ff000] + java.lang.Thread.State: TIMED_WAITING (sleeping) + at java.lang.Thread.sleep0(java.base@21.0.9/Native Method) + at java.lang.Thread.sleep(java.base@21.0.9/Thread.java:509) + at org.apache.rocketmq.client.producer.ProduceAccumulator$GuardForSyncSendService.doWork(ProduceAccumulator.java:109) + at org.apache.rocketmq.client.producer.ProduceAccumulator$GuardForSyncSendService.run(ProduceAccumulator.java:84) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"Client_192.168.9.14@6488#167351209475700_GuardForAsyncSend" #64 [29332] prio=5 os_prio=0 cpu=4062.50ms elapsed=2034.18s tid=0x00000206fb997060 nid=29332 waiting on condition [0x000000a9587ff000] + java.lang.Thread.State: TIMED_WAITING (sleeping) + at java.lang.Thread.sleep0(java.base@21.0.9/Native Method) + at java.lang.Thread.sleep(java.base@21.0.9/Thread.java:509) + at org.apache.rocketmq.client.producer.ProduceAccumulator$GuardForAsyncSendService.doWork(ProduceAccumulator.java:154) + at org.apache.rocketmq.client.producer.ProduceAccumulator$GuardForAsyncSendService.run(ProduceAccumulator.java:131) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-1" #65 [20552] daemon prio=5 os_prio=0 cpu=203.12ms elapsed=2033.58s tid=0x00000206fb999130 nid=20552 waiting on condition [0x000000a9588fe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-2" #66 [32148] daemon prio=5 os_prio=0 cpu=390.62ms elapsed=2033.58s tid=0x00000206fb995cb0 nid=32148 waiting on condition [0x000000a9589fe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-3" #67 [26732] daemon prio=5 os_prio=0 cpu=125.00ms elapsed=2033.58s tid=0x00000206fb99b890 nid=26732 waiting on condition [0x000000a958aff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-4" #68 [25444] daemon prio=5 os_prio=0 cpu=500.00ms elapsed=2033.58s tid=0x00000206fb9997c0 nid=25444 waiting on condition [0x000000a958bff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-5" #69 [9372] daemon prio=5 os_prio=0 cpu=125.00ms elapsed=2033.58s tid=0x00000206fb99c5b0 nid=9372 runnable [0x000000a958cf8000] + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.Net.poll(java.base@21.0.9/Native Method) + at sun.nio.ch.NioSocketImpl.park(java.base@21.0.9/NioSocketImpl.java:191) + at sun.nio.ch.NioSocketImpl.park(java.base@21.0.9/NioSocketImpl.java:201) + at sun.nio.ch.NioSocketImpl.implRead(java.base@21.0.9/NioSocketImpl.java:309) + at sun.nio.ch.NioSocketImpl.read(java.base@21.0.9/NioSocketImpl.java:346) + at sun.nio.ch.NioSocketImpl$1.read(java.base@21.0.9/NioSocketImpl.java:796) + at java.net.Socket$SocketInputStream.read(java.base@21.0.9/Socket.java:1099) + at com.mysql.cj.protocol.ReadAheadInputStream.fill(ReadAheadInputStream.java:107) + at com.mysql.cj.protocol.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:150) + at com.mysql.cj.protocol.ReadAheadInputStream.read(ReadAheadInputStream.java:180) + - locked <0x000000068ee69208> (a com.mysql.cj.protocol.ReadAheadInputStream) + at java.io.FilterInputStream.read(java.base@21.0.9/FilterInputStream.java:119) + at com.mysql.cj.protocol.FullReadInputStream.readFully(FullReadInputStream.java:64) + at com.mysql.cj.protocol.a.SimplePacketReader.readHeaderLocal(SimplePacketReader.java:81) + at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:63) + at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:45) + at com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:52) + at com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:41) + at com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:54) + at com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:44) + at com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:576) + at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:762) + at com.mysql.cj.protocol.a.NativeProtocol.sendCommand(NativeProtocol.java:701) + at com.mysql.cj.protocol.a.NativeProtocol.sendQueryPacket(NativeProtocol.java:1050) + at com.mysql.cj.NativeSession.execSQL(NativeSession.java:660) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:889) + - locked <0x000000068ee66c78> (a com.mysql.cj.jdbc.ConnectionImpl) + at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:354) + - locked <0x000000068ee66c78> (a com.mysql.cj.jdbc.ConnectionImpl) + at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44) + at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java) + at java.lang.invoke.LambdaForm$DMH/0x00000206810d2c00.invokeInterface(java.base@21.0.9/LambdaForm$DMH) + at java.lang.invoke.LambdaForm$MH/0x00000206811f8400.invoke(java.base@21.0.9/LambdaForm$MH) + at java.lang.invoke.Invokers$Holder.invokeExact_MT(java.base@21.0.9/Invokers$Holder) + at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.9/DirectMethodHandleAccessor.java:153) + at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.9/DirectMethodHandleAccessor.java:103) + at java.lang.reflect.Method.invoke(java.base@21.0.9/Method.java:580) + at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:58) + at jdk.proxy3.$Proxy198.execute(jdk.proxy3/Unknown Source) + at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:48) + at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:75) + at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) + at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) + at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) + at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197) + at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:184) + at java.lang.invoke.LambdaForm$DMH/0x0000020681588800.invokeInterface(java.base@21.0.9/LambdaForm$DMH) + at java.lang.invoke.LambdaForm$MH/0x0000020681c38c00.invoke(java.base@21.0.9/LambdaForm$MH) + at java.lang.invoke.LambdaForm$MH/0x00000206810c8000.invokeExact_MT(java.base@21.0.9/LambdaForm$MH) + at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.9/DirectMethodHandleAccessor.java:155) + at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.9/DirectMethodHandleAccessor.java:103) + at java.lang.reflect.Method.invoke(java.base@21.0.9/Method.java:580) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2.$Proxy119.insert(jdk.proxy2/Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272) + at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:59) + at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:152) + at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) + at jdk.proxy2.$Proxy122.insert(jdk.proxy2/Unknown Source) + at com.nanri.aiimage.modules.deletebrand.service.DeleteBrandRunService.run(DeleteBrandRunService.java:103) + at java.lang.invoke.LambdaForm$DMH/0x0000020681120c00.invokeVirtual(java.base@21.0.9/LambdaForm$DMH) + at java.lang.invoke.LambdaForm$MH/0x00000206810b0400.invoke(java.base@21.0.9/LambdaForm$MH) + at java.lang.invoke.Invokers$Holder.invokeExact_MT(java.base@21.0.9/Invokers$Holder) + at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.9/DirectMethodHandleAccessor.java:154) + at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.9/DirectMethodHandleAccessor.java:103) + at java.lang.reflect.Method.invoke(java.base@21.0.9/Method.java:580) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) + at com.nanri.aiimage.modules.deletebrand.service.DeleteBrandRunService$$SpringCGLIB$$0.run() + at com.nanri.aiimage.modules.deletebrand.controller.DeleteBrandRunController.run(DeleteBrandRunController.java:54) + at java.lang.invoke.LambdaForm$DMH/0x0000020681120c00.invokeVirtual(java.base@21.0.9/LambdaForm$DMH) + at java.lang.invoke.LambdaForm$MH/0x00000206810b0400.invoke(java.base@21.0.9/LambdaForm$MH) + at java.lang.invoke.Invokers$Holder.invokeExact_MT(java.base@21.0.9/Invokers$Holder) + at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.9/DirectMethodHandleAccessor.java:154) + at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.9/DirectMethodHandleAccessor.java:103) + at java.lang.reflect.Method.invoke(java.base@21.0.9/Method.java:580) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at com.nanri.aiimage.config.RequestTraceFilter.doFilterInternal(RequestTraceFilter.java:48) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$$Lambda/0x0000020681ac1a68.doFilter(Unknown Source) + at org.springframework.security.web.ObservationFilterChainDecorator$FilterObservation$SimpleFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:479) + at org.springframework.security.web.ObservationFilterChainDecorator$FilterObservation$SimpleFilterObservation$$Lambda/0x0000020681aca0a8.doFilter(Unknown Source) + at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:340) + at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation$$Lambda/0x0000020681aca2c0.doFilter(Unknown Source) + at org.springframework.security.web.ObservationFilterChainDecorator.lambda$wrapSecured$0(ObservationFilterChainDecorator.java:82) + at org.springframework.security.web.ObservationFilterChainDecorator$$Lambda/0x0000020681ac1e98.doFilter(Unknown Source) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:128) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:181) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter$$Lambda/0x0000020681ac3c50.doFilter(Unknown Source) + at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$0(ObservationFilterChainDecorator.java:323) + at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation$$Lambda/0x0000020681ac3e88.doFilter(Unknown Source) + at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:224) + at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector$$Lambda/0x0000020681914658.doFilter(Unknown Source) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:362) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:278) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:113) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-6" #70 [35160] daemon prio=5 os_prio=0 cpu=31.25ms elapsed=2033.58s tid=0x00000206fb99bf20 nid=35160 waiting on condition [0x000000a958dfe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-7" #71 [6692] daemon prio=5 os_prio=0 cpu=62.50ms elapsed=2033.58s tid=0x00000206fb99b200 nid=6692 waiting on condition [0x000000a958efe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-8" #72 [12476] daemon prio=5 os_prio=0 cpu=31.25ms elapsed=2033.58s tid=0x00000206fb999e50 nid=12476 waiting on condition [0x000000a958ffe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-9" #73 [26972] daemon prio=5 os_prio=0 cpu=109.38ms elapsed=2033.58s tid=0x00000206fb99a4e0 nid=26972 waiting on condition [0x000000a9590ff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-exec-10" #74 [35860] daemon prio=5 os_prio=0 cpu=62.50ms elapsed=2033.58s tid=0x00000206fb99ab70 nid=35860 waiting on condition [0x000000a9591ff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb49ee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117) + at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1175) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-Poller" #75 [28396] daemon prio=5 os_prio=0 cpu=109.38ms elapsed=2033.58s tid=0x00000206f613bc10 nid=28396 runnable [0x000000a9592ff000] + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.WEPoll.wait(java.base@21.0.9/Native Method) + at sun.nio.ch.WEPollSelectorImpl.doSelect(java.base@21.0.9/WEPollSelectorImpl.java:114) + at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@21.0.9/SelectorImpl.java:130) + - locked <0x000000068eb0e360> (a sun.nio.ch.Util$2) + - locked <0x000000068eb0e300> (a sun.nio.ch.WEPollSelectorImpl) + at sun.nio.ch.SelectorImpl.select(java.base@21.0.9/SelectorImpl.java:142) + at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:757) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"http-nio-18080-Acceptor" #76 [1948] daemon prio=5 os_prio=0 cpu=15.62ms elapsed=2033.58s tid=0x00000206f613aef0 nid=1948 runnable [0x000000a9593ff000] + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.Net.accept(java.base@21.0.9/Native Method) + at sun.nio.ch.ServerSocketChannelImpl.implAccept(java.base@21.0.9/ServerSocketChannelImpl.java:433) + at sun.nio.ch.ServerSocketChannelImpl.accept(java.base@21.0.9/ServerSocketChannelImpl.java:399) + at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:518) + at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:71) + at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:128) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"aiimage-scheduling-1" #77 [14256] prio=5 os_prio=0 cpu=546.88ms elapsed=2033.55s tid=0x00000206f613dce0 nid=14256 waiting on condition [0x000000a9594fe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068e2666c0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1177) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"aiimage-scheduling-2" #78 [31968] prio=5 os_prio=0 cpu=328.12ms elapsed=2033.55s tid=0x00000206f613b580 nid=31968 waiting on condition [0x000000a9595ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068e2666c0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"aiimage-scheduling-3" #79 [13816] prio=5 os_prio=0 cpu=1671.88ms elapsed=2033.55s tid=0x00000206f613f090 nid=13816 waiting on condition [0x000000a9596ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068e2666c0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"aiimage-scheduling-4" #80 [28896] prio=5 os_prio=0 cpu=343.75ms elapsed=2033.55s tid=0x00000206f613ea00 nid=28896 waiting on condition [0x000000a9597fe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068e2666c0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1177) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"lettuce-nioEventLoop-4-1" #81 [32980] daemon prio=5 os_prio=0 cpu=109.38ms elapsed=2033.11s tid=0x00000206f613c2a0 nid=32980 runnable [0x000000a9599fe000] + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.WEPoll.wait(java.base@21.0.9/Native Method) + at sun.nio.ch.WEPollSelectorImpl.doSelect(java.base@21.0.9/WEPollSelectorImpl.java:114) + at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@21.0.9/SelectorImpl.java:130) + - locked <0x000000068eb00fa0> (a io.netty.channel.nio.SelectedSelectionKeySet) + - locked <0x000000068eb00f40> (a sun.nio.ch.WEPollSelectorImpl) + at sun.nio.ch.SelectorImpl.select(java.base@21.0.9/SelectorImpl.java:147) + at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68) + at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:887) + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:526) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"HikariPool-1 housekeeper" #82 [29912] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=2032.86s tid=0x00000206f613c930 nid=29912 waiting on condition [0x000000a959aff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068eb28cf8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"DestroyJavaVM" #84 [15708] prio=5 os_prio=0 cpu=6906.25ms elapsed=2032.85s tid=0x00000206f6140440 nid=15708 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"boundedElastic-evictor-1" #85 [18992] daemon prio=5 os_prio=0 cpu=15.62ms elapsed=2010.51s tid=0x00000206f613fdb0 nid=18992 waiting on condition [0x000000a955dfe000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068f347428> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@21.0.9/AbstractQueuedSynchronizer.java:1763) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1182) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"lettuce-nioEventLoop-4-2" #87 [29928] daemon prio=5 os_prio=0 cpu=15.62ms elapsed=2010.51s tid=0x00000206f6140ad0 nid=29928 runnable [0x000000a9561fe000] + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.WEPoll.wait(java.base@21.0.9/Native Method) + at sun.nio.ch.WEPollSelectorImpl.doSelect(java.base@21.0.9/WEPollSelectorImpl.java:114) + at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@21.0.9/SelectorImpl.java:130) + - locked <0x000000068eb22280> (a io.netty.channel.nio.SelectedSelectionKeySet) + - locked <0x000000068eb22220> (a sun.nio.ch.WEPollSelectorImpl) + at sun.nio.ch.SelectorImpl.select(java.base@21.0.9/SelectorImpl.java:147) + at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68) + at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:887) + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:526) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"lettuce-eventExecutorLoop-1-1" #112 [34372] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=1024.00s tid=0x00000206f6141e80 nid=34372 waiting on condition [0x000000a954bfe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068dc62420> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at io.netty.util.concurrent.SingleThreadEventExecutor.takeTask(SingleThreadEventExecutor.java:243) + at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:64) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"lettuce-nioEventLoop-4-3" #113 [14056] daemon prio=5 os_prio=0 cpu=78.12ms elapsed=1023.99s tid=0x00000206f6141160 nid=14056 runnable [0x000000a954cfe000] + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.WEPoll.wait(java.base@21.0.9/Native Method) + at sun.nio.ch.WEPollSelectorImpl.doSelect(java.base@21.0.9/WEPollSelectorImpl.java:114) + at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@21.0.9/SelectorImpl.java:130) + - locked <0x000000068ec204a0> (a io.netty.channel.nio.SelectedSelectionKeySet) + - locked <0x000000068ec214c8> (a sun.nio.ch.WEPollSelectorImpl) + at sun.nio.ch.SelectorImpl.select(java.base@21.0.9/SelectorImpl.java:147) + at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68) + at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:887) + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:526) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"OkHttp TaskRunner" #121 [37016] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=337.15s tid=0x00000206fbd56be0 nid=37016 waiting on condition [0x000000a9598ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068fff7390> (a java.util.concurrent.SynchronousQueue$Transferer) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:410) + at java.util.concurrent.LinkedTransferQueue$DualNode.await(java.base@21.0.9/LinkedTransferQueue.java:452) + at java.util.concurrent.SynchronousQueue$Transferer.xferLifo(java.base@21.0.9/SynchronousQueue.java:194) + at java.util.concurrent.SynchronousQueue.xfer(java.base@21.0.9/SynchronousQueue.java:235) + at java.util.concurrent.SynchronousQueue.poll(java.base@21.0.9/SynchronousQueue.java:338) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1069) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"Okio Watchdog" #122 [18768] daemon prio=5 os_prio=0 cpu=15.62ms elapsed=337.15s tid=0x00000206fbd56550 nid=18768 waiting on condition [0x000000a9572ff000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068ffece98> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.9/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1852) + at okio.AsyncTimeout$Companion.awaitTimeout$okio(AsyncTimeout.kt:320) + at okio.AsyncTimeout$Watchdog.run(AsyncTimeout.kt:186) + +"task-file-job-dispatch-1" #125 [37848] prio=5 os_prio=0 cpu=1515.62ms elapsed=335.26s tid=0x00000206fbd54b10 nid=37848 waiting on condition [0x000000a956cff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068e362240> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"Java2D Disposer" #129 [13036] daemon prio=10 os_prio=2 cpu=0.00ms elapsed=334.37s tid=0x00000206fbd58620 nid=13036 waiting on condition [0x000000a959efe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068fdafd50> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.lang.ref.ReferenceQueue.await(java.base@21.0.9/ReferenceQueue.java:67) + at java.lang.ref.ReferenceQueue.remove0(java.base@21.0.9/ReferenceQueue.java:158) + at java.lang.ref.ReferenceQueue.remove(java.base@21.0.9/ReferenceQueue.java:234) + at sun.java2d.Disposer.run(java.desktop@21.0.9/Disposer.java:145) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"task-file-job-dispatch-2" #131 [33976] prio=5 os_prio=0 cpu=546.88ms elapsed=333.03s tid=0x00000206fbd59340 nid=33976 waiting on condition [0x000000a959fff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068e362240> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"boundedElastic-2" #208 [22740] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=44.42s tid=0x00000206ff0af860 nid=22740 waiting on condition [0x000000a954afe000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x00000007ffd58b90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:1170) + at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@21.0.9/ScheduledThreadPoolExecutor.java:899) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.9/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"lettuce-eventExecutorLoop-1-2" #209 [2160] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=39.39s tid=0x00000206ff0b2650 nid=2160 waiting on condition [0x000000a9562ff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068dc62200> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at io.netty.util.concurrent.SingleThreadEventExecutor.takeTask(SingleThreadEventExecutor.java:243) + at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:64) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"OkHttp TaskRunner" #210 [37308] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=36.98s tid=0x00000206ff0b1fc0 nid=37308 in Object.wait() [0x000000a956bff000] + java.lang.Thread.State: TIMED_WAITING (on object monitor) + at java.lang.Object.wait0(java.base@21.0.9/Native Method) + - waiting on + at java.lang.Object.wait(java.base@21.0.9/Object.java:366) + at java.lang.Object.wait(java.base@21.0.9/Object.java:488) + at okhttp3.internal.concurrent.TaskRunner$RealBackend.coordinatorWait(TaskRunner.kt:294) + at okhttp3.internal.concurrent.TaskRunner.awaitTaskToRun(TaskRunner.kt:218) + at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:59) + - locked <0x000000068ffeefb0> (a okhttp3.internal.concurrent.TaskRunner) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.9/ThreadPoolExecutor.java:1144) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.9/ThreadPoolExecutor.java:642) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"lettuce-eventExecutorLoop-1-3" #211 [35152] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=25.18s tid=0x00000206ff0b2ce0 nid=35152 waiting on condition [0x000000a9573ff000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.9/Native Method) + - parking to wait for <0x000000068dc61fe0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.9/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.9/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.9/ForkJoinPool.java:3778) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.9/ForkJoinPool.java:3723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.9/AbstractQueuedSynchronizer.java:1712) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.9/LinkedBlockingQueue.java:435) + at io.netty.util.concurrent.SingleThreadEventExecutor.takeTask(SingleThreadEventExecutor.java:243) + at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:64) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"lettuce-nioEventLoop-4-4" #212 [32884] daemon prio=5 os_prio=0 cpu=0.00ms elapsed=25.18s tid=0x00000206ff0b3370 nid=32884 runnable [0x000000a9574fe000] + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.WEPoll.wait(java.base@21.0.9/Native Method) + at sun.nio.ch.WEPollSelectorImpl.doSelect(java.base@21.0.9/WEPollSelectorImpl.java:114) + at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@21.0.9/SelectorImpl.java:130) + - locked <0x000000068ec066d0> (a io.netty.channel.nio.SelectedSelectionKeySet) + - locked <0x000000068ec066e8> (a sun.nio.ch.WEPollSelectorImpl) + at sun.nio.ch.SelectorImpl.select(java.base@21.0.9/SelectorImpl.java:147) + at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68) + at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:887) + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:526) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.runWith(java.base@21.0.9/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.9/Thread.java:1583) + +"G1 Conc#2" os_prio=2 cpu=218.75ms elapsed=2041.95s tid=0x00000206f735ee50 nid=18900 runnable + +"G1 Conc#1" os_prio=2 cpu=203.12ms elapsed=2041.96s tid=0x00000206f735eaa0 nid=33484 runnable + +"GC Thread#12" os_prio=2 cpu=62.50ms elapsed=2042.22s tid=0x00000206f785f210 nid=31868 runnable + +"GC Thread#11" os_prio=2 cpu=62.50ms elapsed=2042.22s tid=0x00000206f6581a70 nid=4496 runnable + +"GC Thread#10" os_prio=2 cpu=109.38ms elapsed=2042.22s tid=0x00000206f6253e90 nid=33260 runnable + +"GC Thread#9" os_prio=2 cpu=62.50ms elapsed=2042.22s tid=0x00000206f64433f0 nid=37096 runnable + +"GC Thread#8" os_prio=2 cpu=93.75ms elapsed=2043.16s tid=0x00000206f4bfe950 nid=33308 runnable + +"GC Thread#7" os_prio=2 cpu=93.75ms elapsed=2043.16s tid=0x00000206f4bfe5a0 nid=29340 runnable + +"GC Thread#6" os_prio=2 cpu=109.38ms elapsed=2043.16s tid=0x00000206f4bfd5e0 nid=30004 runnable + +"GC Thread#5" os_prio=2 cpu=109.38ms elapsed=2043.16s tid=0x00000206f4bfd230 nid=37836 runnable + +"GC Thread#4" os_prio=2 cpu=78.12ms elapsed=2043.16s tid=0x00000206f535ee00 nid=28080 runnable + +"GC Thread#1" os_prio=2 cpu=93.75ms elapsed=2043.16s tid=0x00000206f4dddd20 nid=7744 runnable + +"GC Thread#3" os_prio=2 cpu=62.50ms elapsed=2043.16s tid=0x00000206f535ea50 nid=32244 runnable + +"GC Thread#2" os_prio=2 cpu=78.12ms elapsed=2043.16s tid=0x00000206f4ef5900 nid=36548 runnable + +"VM Thread" os_prio=2 cpu=109.38ms elapsed=2043.38s tid=0x00000206ef850220 nid=36908 runnable + +"VM Periodic Task Thread" os_prio=2 cpu=828.12ms elapsed=2043.38s tid=0x00000206ef839e80 nid=26176 waiting on condition + +"G1 Service" os_prio=2 cpu=78.12ms elapsed=2043.39s tid=0x00000206ef708f10 nid=29916 runnable + +"G1 Refine#0" os_prio=2 cpu=875.00ms elapsed=2043.39s tid=0x00000206ef7076d0 nid=32744 runnable + +"G1 Conc#0" os_prio=2 cpu=203.12ms elapsed=2043.39s tid=0x00000206cdf35680 nid=10956 runnable + +"G1 Main Marker" os_prio=2 cpu=0.00ms elapsed=2043.39s tid=0x00000206cdf33740 nid=17824 runnable + +"GC Thread#0" os_prio=2 cpu=93.75ms elapsed=2043.39s tid=0x00000206cdf26720 nid=36252 runnable + +JNI global refs: 52, weak refs: 1 + diff --git a/backend-java/src/main/java/com/nanri/aiimage/config/AppearancePatentProperties.java b/backend-java/src/main/java/com/nanri/aiimage/config/AppearancePatentProperties.java index b75b930..29e672e 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/config/AppearancePatentProperties.java +++ b/backend-java/src/main/java/com/nanri/aiimage/config/AppearancePatentProperties.java @@ -11,6 +11,8 @@ public class AppearancePatentProperties { private String cozeWorkflowId = "7632683471312355338"; private String cozeToken = ""; private int cozeBatchSize = 10; + private int cozeConnectTimeoutMillis = 10000; + private int cozeReadTimeoutMillis = 60000; private int staleTimeoutMinutes = 20; private String staleFinalizeCron = "0 */2 * * * *"; } diff --git a/backend-java/src/main/java/com/nanri/aiimage/config/DeleteBrandProgressProperties.java b/backend-java/src/main/java/com/nanri/aiimage/config/DeleteBrandProgressProperties.java index 3e17430..7c79101 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/config/DeleteBrandProgressProperties.java +++ b/backend-java/src/main/java/com/nanri/aiimage/config/DeleteBrandProgressProperties.java @@ -7,6 +7,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "aiimage.delete-brand-progress") public class DeleteBrandProgressProperties { private long heartbeatTimeoutMinutes = 15; + private long deleteBrandInitialTimeoutMinutes = 20; private String staleCheckCron = "*/30 * * * * *"; /** diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/client/AppearancePatentCozeClient.java b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/client/AppearancePatentCozeClient.java index e1de001..6518717 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/client/AppearancePatentCozeClient.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/client/AppearancePatentCozeClient.java @@ -9,11 +9,14 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Component; +import org.springframework.util.StreamUtils; import org.springframework.web.client.RestClient; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; @Component @@ -33,29 +36,72 @@ public class AppearancePatentCozeClient { return rows.stream().map(this::copy).toList(); } try { - String raw = postWorkflow(rows, prompt); - List results = parseResults(raw); - List merged = new ArrayList<>(); - for (int i = 0; i < rows.size(); i++) { - AppearancePatentResultRowDto row = copy(rows.get(i)); - if (i < results.size()) { - CozeResult result = results.get(i); - row.setTitleRisk(result.title()); - row.setAppearanceRisk(result.appearance()); - row.setPatentRisk(result.patent()); - row.setConclusion(result.result()); - } - merged.add(row); - } - return merged; + return inspectWithFallback(rows, prompt); } catch (Exception ex) { - log.warn("[appearance-patent] coze batch failed size={} err={}", rows.size(), ex.getMessage()); - return rows.stream().map(this::copy).toList(); + String failureMessage = failureMessage(ex); + log.warn("[appearance-patent] coze batch failed size={} err={}", rows.size(), failureMessage); + return rows.stream().map(this::copy).map(row -> markFailed(row, failureMessage)).toList(); } } + private List inspectWithFallback(List rows, String prompt) { + try { + if (rows.size() == 1) { + return inspectSingleRowWithRetry(rows, prompt); + } + InspectAttempt attempt = inspectOnce(rows, prompt); + if (attempt.resolvedCount() < rows.size()) { + throw new PartialCozeResultException(attempt.resolvedCount(), rows.size(), attempt.rawResultCount()); + } + return attempt.mergedRows(); + } catch (Exception ex) { + if (shouldSplitBatch(rows, ex)) { + int middle = rows.size() / 2; + log.warn("[appearance-patent] coze batch fallback split size={} left={} right={} err={}", + rows.size(), middle, rows.size() - middle, failureMessage(ex)); + List merged = new ArrayList<>(rows.size()); + merged.addAll(inspectWithFallback(rows.subList(0, middle), prompt)); + merged.addAll(inspectWithFallback(rows.subList(middle, rows.size()), prompt)); + return merged; + } + throw propagate(ex); + } + } + + private List inspectSingleRowWithRetry(List rows, String prompt) throws Exception { + AppearancePatentResultRowDto row = rows.getFirst(); + PartialCozeResultException lastFailure = null; + for (int attemptIndex = 1; attemptIndex <= 3; attemptIndex++) { + InspectAttempt attempt = inspectOnce(rows, prompt); + if (attempt.resolvedCount() == rows.size()) { + return attempt.mergedRows(); + } + log.warn("[appearance-patent] coze single unresolved attempt={} rowId={} asin={} country={} title={} url={} raw={}", + attemptIndex, + row.getId(), + row.getAsin(), + row.getCountry(), + abbreviate(row.getTitle(), 120), + abbreviate(row.getUrl(), 120), + abbreviate(attempt.raw(), 500)); + lastFailure = new PartialCozeResultException(attempt.resolvedCount(), rows.size(), attempt.rawResultCount()); + } + throw lastFailure == null ? new PartialCozeResultException(0, rows.size(), 0) : lastFailure; + } + + private InspectAttempt inspectOnce(List rows, String prompt) throws Exception { + String raw = postWorkflow(rows, prompt); + List results = parseResults(raw); + List merged = mergeRows(rows, results); + return new InspectAttempt(raw, merged, resolvedCount(merged), results.size()); + } + private String postWorkflow(List rows, String prompt) { Map parameters = new LinkedHashMap<>(); + parameters.put("row_id_list", rows.stream().map(row -> nonBlank(row.getId(), "")).toList()); + parameters.put("asin_list", rows.stream().map(row -> nonBlank(row.getAsin(), "")).toList()); + parameters.put("country_list", rows.stream().map(row -> nonBlank(row.getCountry(), "")).toList()); + parameters.put("row_key_list", rows.stream().map(this::rowKey).toList()); parameters.put("title_list", rows.stream().map(row -> nonBlank(row.getTitle(), row.getAsin())).toList()); parameters.put("url_list", rows.stream().map(row -> nonBlank(row.getUrl(), "")).toList()); parameters.put("prompt", prompt == null ? "" : prompt); @@ -71,7 +117,10 @@ public class AppearancePatentCozeClient { headers.setContentType(MediaType.APPLICATION_JSON); }); request.body(body); - return request.retrieve().body(String.class); + return request.exchange((clientRequest, clientResponse) -> { + byte[] responseBytes = StreamUtils.copyToByteArray(clientResponse.getBody()); + return responseBytes.length == 0 ? "" : new String(responseBytes, StandardCharsets.UTF_8); + }); } private List parseResults(String raw) throws Exception { @@ -89,6 +138,9 @@ public class AppearancePatentCozeClient { if (array.isArray()) { for (JsonNode node : array) { results.add(new CozeResult( + text(firstNonNull(node.get("row_id"), firstNonNull(node.get("rowId"), node.get("id")))), + text(node.get("asin")), + text(firstNonNull(node.get("country"), node.get("site"))), text(node.get("title")), text(node.get("appearance")), text(firstNonNull(node.get("patent"), node.get("patent "))), @@ -99,10 +151,51 @@ public class AppearancePatentCozeClient { return results; } + private List mergeRows(List rows, List results) { + Map resultByCompositeKey = new LinkedHashMap<>(); + Map resultByRowId = new LinkedHashMap<>(); + for (CozeResult result : results) { + String compositeKey = rowKey(result.rowId(), result.asin(), result.country()); + if (!compositeKey.isBlank()) { + resultByCompositeKey.putIfAbsent(compositeKey, result); + } + String rowIdKey = normalize(result.rowId()); + if (!rowIdKey.isBlank()) { + resultByRowId.putIfAbsent(rowIdKey, result); + } + } + + List merged = new ArrayList<>(rows.size()); + boolean allowIndexFallback = results.size() == rows.size(); + for (int i = 0; i < rows.size(); i++) { + AppearancePatentResultRowDto row = copy(rows.get(i)); + CozeResult result = resultByCompositeKey.get(rowKey(row.getId(), row.getAsin(), row.getCountry())); + if (result == null) { + result = resultByRowId.get(normalize(row.getId())); + } + if (result == null && allowIndexFallback && i < results.size()) { + result = results.get(i); + } + applyResult(row, result); + merged.add(row); + } + return merged; + } + + private void applyResult(AppearancePatentResultRowDto row, CozeResult result) { + if (row == null || result == null) { + return; + } + row.setTitleRisk(result.title()); + row.setAppearanceRisk(result.appearance()); + row.setPatentRisk(result.patent()); + row.setConclusion(result.result()); + } + private RestClient restClient() { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); - requestFactory.setConnectTimeout(10000); - requestFactory.setReadTimeout(60000); + requestFactory.setConnectTimeout(properties.getCozeConnectTimeoutMillis()); + requestFactory.setReadTimeout(properties.getCozeReadTimeoutMillis()); return RestClient.builder().requestFactory(requestFactory).build(); } @@ -122,6 +215,67 @@ public class AppearancePatentCozeClient { return row; } + private AppearancePatentResultRowDto markFailed(AppearancePatentResultRowDto row, String failureMessage) { + if (row.getError() == null || row.getError().isBlank()) { + row.setError(failureMessage); + } + if (row.getConclusion() == null || row.getConclusion().isBlank()) { + row.setConclusion(failureMessage); + } + return row; + } + + private boolean shouldSplitBatch(List rows, Exception ex) { + return rows != null && rows.size() > 1 && isRetryableBatchFailure(ex); + } + + private boolean isRetryableBatchFailure(Exception ex) { + if (ex instanceof PartialCozeResultException) { + return true; + } + String message = ex == null ? "" : nonBlank(ex.getMessage(), ""); + return message.contains("Workflow node execution limit exceeded") + || message.contains("Read timed out") + || message.contains("Connection reset") + || message.contains("I/O error on POST request") + || message.toLowerCase(Locale.ROOT).contains("timeout"); + } + + private int resolvedCount(List rows) { + int resolved = 0; + for (AppearancePatentResultRowDto row : rows) { + if (hasResolvedCozeFields(row)) { + resolved++; + } + } + return resolved; + } + + private boolean hasResolvedCozeFields(AppearancePatentResultRowDto row) { + if (row == null) { + return false; + } + return !normalize(row.getTitleRisk()).isBlank() + || !normalize(row.getAppearanceRisk()).isBlank() + || !normalize(row.getPatentRisk()).isBlank() + || !normalize(row.getConclusion()).isBlank(); + } + + private String abbreviate(String value, int maxLength) { + String normalized = value == null ? "" : value.trim(); + if (normalized.length() <= maxLength) { + return normalized; + } + return normalized.substring(0, Math.max(0, maxLength - 3)) + "..."; + } + + private RuntimeException propagate(Exception ex) { + if (ex instanceof RuntimeException runtimeException) { + return runtimeException; + } + return new IllegalStateException(nonBlank(ex.getMessage(), "Coze call failed"), ex); + } + private JsonNode firstNonNull(JsonNode left, JsonNode right) { return left == null || left.isNull() ? right : left; } @@ -134,6 +288,38 @@ public class AppearancePatentCozeClient { return value == null || value.isBlank() ? fallback : value; } + private String normalize(String value) { + return value == null ? "" : value.replace("\ufeff", "").replace("\u3000", " ").trim(); + } + + private String rowKey(AppearancePatentResultRowDto row) { + if (row == null) { + return ""; + } + return rowKey(row.getId(), row.getAsin(), row.getCountry()); + } + + private String rowKey(String rowId, String asin, String country) { + return normalize(rowId) + "::" + normalize(asin).toUpperCase(Locale.ROOT) + "::" + normalize(country); + } + + private String failureMessage(Exception ex) { + if (ex instanceof PartialCozeResultException partial) { + return "Coze返回结果不完整(" + partial.resolvedCount() + "/" + partial.expectedCount() + ")"; + } + String message = ex == null ? null : ex.getMessage(); + if (message == null || message.isBlank()) { + return "Coze调用失败"; + } + if (message.contains("Workflow node execution limit exceeded")) { + return "Coze工作流节点执行超限,请检查工作流配置"; + } + if (message.contains("Read timed out")) { + return "Coze调用超时,请稍后重试"; + } + return "Coze调用失败: " + message; + } + private String stripBearer(String token) { String normalized = token == null ? "" : token.trim(); return normalized.regionMatches(true, 0, "Bearer ", 0, 7) ? normalized.substring(7).trim() : normalized; @@ -151,6 +337,49 @@ public class AppearancePatentCozeClient { return base + suffix; } - private record CozeResult(String title, String appearance, String patent, String result) { + private record CozeResult( + String rowId, + String asin, + String country, + String title, + String appearance, + String patent, + String result + ) { + } + + private record InspectAttempt( + String raw, + List mergedRows, + int resolvedCount, + int rawResultCount + ) { + } + + private static final class PartialCozeResultException extends RuntimeException { + + private final int resolvedCount; + private final int expectedCount; + private final int rawResultCount; + + private PartialCozeResultException(int resolvedCount, int expectedCount, int rawResultCount) { + super("partial-result resolved=" + resolvedCount + "/" + expectedCount + " raw=" + rawResultCount); + this.resolvedCount = resolvedCount; + this.expectedCount = expectedCount; + this.rawResultCount = rawResultCount; + } + + private int resolvedCount() { + return resolvedCount; + } + + private int expectedCount() { + return expectedCount; + } + + @SuppressWarnings("unused") + private int rawResultCount() { + return rawResultCount; + } } } diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/model/vo/AppearancePatentParsedRowVo.java b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/model/vo/AppearancePatentParsedRowVo.java index a286e4f..420e9b4 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/model/vo/AppearancePatentParsedRowVo.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/model/vo/AppearancePatentParsedRowVo.java @@ -16,6 +16,7 @@ public class AppearancePatentParsedRowVo { @Schema(description = "前端展示和 Python 回传使用的 id。整数 id 原样保留,子数据第一条如 2_1 原样保留。", example = "2_1") private String displayId; @Schema(description = "亚马逊 ASIN。", example = "B0CJ8SNXXV") + private String groupKey; private String asin; @Schema(description = "国家或站点。", example = "英国") private String country; diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskCacheService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskCacheService.java index 31e71db..cded051 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskCacheService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskCacheService.java @@ -22,14 +22,14 @@ public class AppearancePatentTaskCacheService { private final StringRedisTemplate stringRedisTemplate; private final ObjectMapper objectMapper; - public void appendPendingRow(Long taskId, Integer chunkIndex, AppearancePatentResultRowDto row) { - if (taskId == null || taskId <= 0 || chunkIndex == null || row == null) { + public void appendPendingRow(Long taskId, String scopeHash, Integer chunkIndex, AppearancePatentResultRowDto row) { + if (taskId == null || taskId <= 0 || scopeHash == null || scopeHash.isBlank() || chunkIndex == null || row == null) { return; } try { stringRedisTemplate.opsForList().rightPush( pendingRowsKey(taskId), - objectMapper.writeValueAsString(new PendingRow(chunkIndex, row)) + objectMapper.writeValueAsString(new PendingRow(scopeHash, chunkIndex, row)) ); stringRedisTemplate.expire(pendingRowsKey(taskId), Duration.ofHours(TTL_HOURS)); touchTaskHeartbeat(taskId); @@ -139,6 +139,6 @@ public class AppearancePatentTaskCacheService { return "appearance-patent:task:heartbeat:" + taskId; } - public record PendingRow(Integer chunkIndex, AppearancePatentResultRowDto row) { + public record PendingRow(String scopeHash, Integer chunkIndex, AppearancePatentResultRowDto row) { } } diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskService.java index d64f984..4e129b5 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/appearancepatent/service/AppearancePatentTaskService.java @@ -49,7 +49,10 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.springframework.dao.DuplicateKeyException; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.support.TransactionTemplate; import java.io.File; import java.io.FileInputStream; @@ -65,6 +68,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.Supplier; @Service @RequiredArgsConstructor @@ -101,6 +105,7 @@ public class AppearancePatentTaskService { private final AppearancePatentProperties properties; private final TaskFileJobService taskFileJobService; private final TransientPayloadStorageService transientPayloadStorageService; + private final PlatformTransactionManager transactionManager; @Transactional public AppearancePatentParseVo parseAndCreateTask(AppearancePatentParseRequest request) { @@ -259,8 +264,16 @@ public class AppearancePatentTaskService { return vo; } - @Transactional public void submitResult(Long taskId, AppearancePatentSubmitResultRequest request) { + if (transactionManager != null) { + SubmitContext context = inNewTransaction(() -> persistSubmittedChunk(taskId, request)); + flushPendingRowsIfNeeded(context.task(), context.forceFlush()); + inNewTransaction(() -> { + completeSubmittedChunk(context); + return null; + }); + return; + } FileTaskEntity task = fileTaskMapper.selectById(taskId); if (task == null || !MODULE_TYPE.equals(task.getModuleType())) { throw new BusinessException("任务不存在"); @@ -302,19 +315,21 @@ public class AppearancePatentTaskService { taskChunkMapper.insert(chunk); } catch (DuplicateKeyException ex) { inserted = false; - transientPayloadStorageService.deletePayloadIfPresent(storedPayload); + // storeChunkPayload uses a deterministic key like chunk-{index}. When two + // concurrent callbacks submit the same chunk, deleting the loser payload here + // can also remove the winner's shared object and break later assembly. log.info("[appearance-patent] duplicate chunk inserted concurrently taskId={} scope={} chunk={}", taskId, scopeKey, chunkIndex); } if (inserted) { for (AppearancePatentResultRowDto rawRow : rawRows) { - taskCacheService.appendPendingRow(taskId, chunkIndex, rawRow); + taskCacheService.appendPendingRow(taskId, scopeHash, chunkIndex, rawRow); } } } else { log.info("[appearance-patent] duplicate chunk ignored taskId={} scope={} chunk={}", taskId, scopeKey, chunkIndex); } - flushPendingRowsIfNeeded(task, scopeHash, Boolean.TRUE.equals(request.getDone())); + flushPendingRowsIfNeeded(task, Boolean.TRUE.equals(request.getDone())); TaskScopeStateEntity scope = taskScopeStateMapper.selectOne(new LambdaQueryWrapper() .eq(TaskScopeStateEntity::getTaskId, taskId) @@ -394,8 +409,28 @@ public class AppearancePatentTaskService { } @Scheduled(cron = "${aiimage.appearance-patent.stale-finalize-cron:0 */2 * * * *}") - @Transactional public void finalizeStaleTasks() { + if (transactionManager != null) { + LocalDateTime threshold = LocalDateTime.now().minusMinutes(Math.max(1, properties.getStaleTimeoutMinutes())); + long thresholdMillis = threshold.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + List tasks = fileTaskMapper.selectList(new LambdaQueryWrapper() + .eq(FileTaskEntity::getModuleType, MODULE_TYPE) + .eq(FileTaskEntity::getStatus, STATUS_RUNNING) + .lt(FileTaskEntity::getUpdatedAt, threshold) + .last("limit 50")); + for (FileTaskEntity task : tasks) { + long heartbeatMillis = taskCacheService.getTaskHeartbeatMillis(task.getId()); + if (heartbeatMillis > thresholdMillis) { + continue; + } + flushPendingRowsIfNeeded(task, true); + inNewTransaction(() -> { + finalizeStaleTask(task.getId(), "Python interrupted before uploading final appearance patent result"); + return null; + }); + } + return; + } LocalDateTime threshold = LocalDateTime.now().minusMinutes(Math.max(1, properties.getStaleTimeoutMinutes())); long thresholdMillis = threshold.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); List tasks = fileTaskMapper.selectList(new LambdaQueryWrapper() @@ -408,11 +443,168 @@ public class AppearancePatentTaskService { if (heartbeatMillis > thresholdMillis) { continue; } - flushPendingRowsIfNeeded(task, DigestUtil.sha256Hex("appearance-patent-" + task.getId()), true); + flushPendingRowsIfNeeded(task, true); finalizeTask(task, "Python interrupted before uploading final appearance patent result", allRowCount(task), true); } } + private SubmitContext persistSubmittedChunk(Long taskId, AppearancePatentSubmitResultRequest request) { + FileTaskEntity task = fileTaskMapper.selectById(taskId); + if (task == null || !MODULE_TYPE.equals(task.getModuleType())) { + throw new BusinessException("浠诲姟涓嶅瓨鍦?"); + } + if (!STATUS_RUNNING.equals(task.getStatus())) { + throw new BusinessException("浠诲姟涓嶆槸杩愯涓姸鎬?"); + } + + int chunkIndex = request.getChunkIndex() == null ? 0 : request.getChunkIndex(); + int chunkTotal = request.getChunkTotal() == null ? 1 : request.getChunkTotal(); + boolean done = Boolean.TRUE.equals(request.getDone()); + String scopeKey = firstNonBlank(request.getSubmissionId(), "task:" + taskId); + String scopeHash = DigestUtil.sha256Hex(scopeKey); + taskCacheService.touchTaskHeartbeat(taskId); + + TaskChunkEntity existing = taskChunkMapper.selectOne(new LambdaQueryWrapper() + .eq(TaskChunkEntity::getTaskId, taskId) + .eq(TaskChunkEntity::getModuleType, MODULE_TYPE) + .eq(TaskChunkEntity::getScopeHash, scopeHash) + .eq(TaskChunkEntity::getChunkIndex, chunkIndex) + .last("limit 1")); + if (existing == null) { + List rawRows = request.getItems() == null ? List.of() : request.getItems(); + String payloadJson = writeJson(rawRows, "缁撴灉搴忓垪鍖栧け璐?"); + + TaskChunkEntity chunk = new TaskChunkEntity(); + chunk.setTaskId(taskId); + chunk.setModuleType(MODULE_TYPE); + chunk.setScopeKey(scopeKey); + chunk.setScopeHash(scopeHash); + chunk.setChunkIndex(chunkIndex); + chunk.setChunkTotal(chunkTotal); + String storedPayload = transientPayloadStorageService.storeChunkPayload(MODULE_TYPE, taskId, scopeHash, chunkIndex, payloadJson); + chunk.setPayloadJson(storedPayload); + chunk.setPayloadHash(DigestUtil.sha256Hex(payloadJson)); + chunk.setCreatedAt(LocalDateTime.now()); + chunk.setUpdatedAt(LocalDateTime.now()); + boolean inserted = true; + try { + taskChunkMapper.insert(chunk); + } catch (DuplicateKeyException ex) { + inserted = false; + log.info("[appearance-patent] duplicate chunk inserted concurrently taskId={} scope={} chunk={}", taskId, scopeKey, chunkIndex); + } + if (inserted) { + for (AppearancePatentResultRowDto rawRow : rawRows) { + taskCacheService.appendPendingRow(taskId, scopeHash, chunkIndex, rawRow); + } + } + } else { + log.info("[appearance-patent] duplicate chunk ignored taskId={} scope={} chunk={}", taskId, scopeKey, chunkIndex); + } + + upsertScopeState(taskId, scopeKey, scopeHash, chunkTotal, request.getError(), done, false); + task.setUpdatedAt(LocalDateTime.now()); + fileTaskMapper.updateById(task); + return new SubmitContext(task, scopeKey, scopeHash, done, request.getError()); + } + + private void completeSubmittedChunk(SubmitContext context) { + FileTaskEntity task = fileTaskMapper.selectById(context.task().getId()); + if (task == null || !MODULE_TYPE.equals(task.getModuleType())) { + throw new BusinessException("浠诲姟涓嶅瓨鍦?"); + } + if (!STATUS_RUNNING.equals(task.getStatus())) { + log.info("[appearance-patent] skip completion because task already finalized taskId={} status={}", + task.getId(), task.getStatus()); + return; + } + upsertScopeState(task.getId(), context.scopeKey(), context.scopeHash(), null, context.error(), context.forceFlush(), true); + if (context.forceFlush() || context.error() != null && !context.error().isBlank()) { + finalizeTask(task, context.error(), allRowCount(task), true); + return; + } + task.setUpdatedAt(LocalDateTime.now()); + fileTaskMapper.updateById(task); + } + + private void finalizeStaleTask(Long taskId, String error) { + FileTaskEntity task = fileTaskMapper.selectById(taskId); + if (task == null || !MODULE_TYPE.equals(task.getModuleType()) || !STATUS_RUNNING.equals(task.getStatus())) { + return; + } + finalizeTask(task, error, allRowCount(task), true); + } + + private void upsertScopeState(Long taskId, + String scopeKey, + String scopeHash, + Integer chunkTotal, + String error, + boolean completed, + boolean cozeDone) { + TaskScopeStateEntity scope = taskScopeStateMapper.selectOne(new LambdaQueryWrapper() + .eq(TaskScopeStateEntity::getTaskId, taskId) + .eq(TaskScopeStateEntity::getModuleType, MODULE_TYPE) + .eq(TaskScopeStateEntity::getScopeHash, scopeHash) + .last("limit 1")); + LocalDateTime now = LocalDateTime.now(); + if (scope == null) { + scope = new TaskScopeStateEntity(); + scope.setTaskId(taskId); + scope.setModuleType(MODULE_TYPE); + scope.setScopeKey(scopeKey); + scope.setScopeHash(scopeHash); + scope.setCreatedAt(now); + } + if (chunkTotal != null) { + scope.setChunkTotal(chunkTotal); + } + scope.setReceivedChunkCount(countChunks(taskId, scopeHash)); + scope.setLastChunkAt(now); + scope.setLastError(error); + scope.setCompleted(completed ? 1 : 0); + scope.setUpdatedAt(now); + scope.setStateJson(cozeDone + ? "{\"phase\":\"RECEIVED\",\"coze\":\"DONE\"}" + : "{\"phase\":\"RECEIVED\",\"coze\":\"PENDING\"}"); + if (scope.getId() == null) { + try { + taskScopeStateMapper.insert(scope); + return; + } catch (DuplicateKeyException ex) { + log.info("[appearance-patent] duplicate scope state inserted concurrently taskId={} scope={}", taskId, scopeKey); + scope = taskScopeStateMapper.selectOne(new LambdaQueryWrapper() + .eq(TaskScopeStateEntity::getTaskId, taskId) + .eq(TaskScopeStateEntity::getModuleType, MODULE_TYPE) + .eq(TaskScopeStateEntity::getScopeHash, scopeHash) + .last("limit 1")); + if (scope == null) { + log.info("[appearance-patent] scope state winner not committed yet, skip duplicate updater taskId={} scope={}", + taskId, scopeKey); + return; + } + if (chunkTotal != null) { + scope.setChunkTotal(chunkTotal); + } + scope.setReceivedChunkCount(countChunks(taskId, scopeHash)); + scope.setLastChunkAt(now); + scope.setLastError(error); + scope.setCompleted(completed ? 1 : 0); + scope.setUpdatedAt(now); + scope.setStateJson(cozeDone + ? "{\"phase\":\"RECEIVED\",\"coze\":\"DONE\"}" + : "{\"phase\":\"RECEIVED\",\"coze\":\"PENDING\"}"); + } + } + taskScopeStateMapper.updateById(scope); + } + + private T inNewTransaction(Supplier action) { + TransactionTemplate template = new TransactionTemplate(transactionManager); + template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); + return template.execute(status -> action.get()); + } + private List applyCozeInBatches(List items, FileTaskEntity task) { if (items == null || items.isEmpty()) { return List.of(); @@ -426,8 +618,10 @@ public class AppearancePatentTaskService { return result; } - private void flushPendingRowsIfNeeded(FileTaskEntity task, String scopeHash, boolean force) { + private void flushPendingRowsIfNeeded(FileTaskEntity task, boolean force) { int batchSize = Math.max(1, properties.getCozeBatchSize()); + Map> allRowsByBaseId = loadAllRowsByBaseId(task); + String prompt = readAiPrompt(task); while (force ? taskCacheService.pendingRowCount(task.getId()) > 0 : taskCacheService.pendingRowCount(task.getId()) >= batchSize) { int drainSize = force ? batchSize : Math.max(1, batchSize); List pendingRows = taskCacheService.drainPendingRows(task.getId(), drainSize); @@ -437,27 +631,47 @@ public class AppearancePatentTaskService { List rawRows = pendingRows.stream() .map(AppearancePatentTaskCacheService.PendingRow::row) .toList(); - List cozeRows = cozeClient.inspect(rawRows, readAiPrompt(task)); + List cozeRows = cozeClient.inspect(rawRows, prompt); + Map> chunkRows = new LinkedHashMap<>(); for (int i = 0; i < pendingRows.size(); i++) { AppearancePatentTaskCacheService.PendingRow pending = pendingRows.get(i); AppearancePatentResultRowDto resultRow = i < cozeRows.size() ? cozeRows.get(i) : pending.row(); - List persistedRows = expandRows(task, List.of(resultRow)); - updateChunkPayload(task.getId(), scopeHash, pending.chunkIndex(), persistedRows); + List expandedRows = expandRows(List.of(resultRow), allRowsByBaseId); + String chunkKey = pending.scopeHash() + "::" + pending.chunkIndex(); + Map mergedRows = + chunkRows.computeIfAbsent(chunkKey, key -> new LinkedHashMap<>()); + for (AppearancePatentResultRowDto expandedRow : expandedRows) { + mergedRows.put(rowKey(expandedRow.getId(), expandedRow.getAsin(), expandedRow.getCountry()), expandedRow); + } + } + for (Map.Entry> entry : chunkRows.entrySet()) { + int delimiter = entry.getKey().lastIndexOf("::"); + if (delimiter <= 0) { + continue; + } + String scopeHash = entry.getKey().substring(0, delimiter); + Integer chunkIndex = Integer.parseInt(entry.getKey().substring(delimiter + 2)); + mergeChunkPayload(task.getId(), scopeHash, chunkIndex, new ArrayList<>(entry.getValue().values())); } } } - private void updateChunkPayload(Long taskId, String scopeHash, Integer chunkIndex, List rows) { + private void mergeChunkPayload(Long taskId, String scopeHash, Integer chunkIndex, List rows) { TaskChunkEntity chunk = taskChunkMapper.selectOne(new LambdaQueryWrapper() .eq(TaskChunkEntity::getTaskId, taskId) .eq(TaskChunkEntity::getModuleType, MODULE_TYPE) .eq(TaskChunkEntity::getScopeHash, scopeHash) .eq(TaskChunkEntity::getChunkIndex, chunkIndex) .last("limit 1")); - if (chunk == null) { + if (chunk == null || rows == null || rows.isEmpty()) { return; } + Map persistedRows = readChunkRows(chunk); + for (AppearancePatentResultRowDto row : rows) { + persistedRows.put(rowKey(row.getId(), row.getAsin(), row.getCountry()), row); + } String payloadJson = writeJson(rows == null ? List.of() : rows, "结果序列化失败"); + payloadJson = writeJson(new ArrayList<>(persistedRows.values()), "appearance patent chunk payload merge failed"); String storedPayload = transientPayloadStorageService.storeChunkPayload(MODULE_TYPE, taskId, scopeHash, chunkIndex, payloadJson); transientPayloadStorageService.deleteReplacedPayloadIfNeeded(chunk.getPayloadJson(), storedPayload); chunk.setPayloadJson(storedPayload); @@ -466,16 +680,15 @@ public class AppearancePatentTaskService { taskChunkMapper.updateById(chunk); } - private List expandRows(FileTaskEntity task, List representatives) { + private List expandRows(List representatives, + Map> allRowsByBaseId) { if (representatives == null || representatives.isEmpty()) { return List.of(); } - Map> allRowsByBaseId = loadAllRowsByBaseId(task); List result = new ArrayList<>(); Set emittedKeys = new LinkedHashSet<>(); for (AppearancePatentResultRowDto representative : representatives) { - String baseId = baseId(representative.getId()); - List siblings = allRowsByBaseId.get(baseId); + List siblings = resolveSiblingRows(representative, allRowsByBaseId); if (siblings == null || siblings.isEmpty()) { result.add(representative); continue; @@ -491,14 +704,40 @@ public class AppearancePatentTaskService { return result; } - private Map> loadAllRowsByBaseId(FileTaskEntity task) { - Map> result = new LinkedHashMap<>(); - try { - for (AppearancePatentParsedRowVo row : readParsedPayload(task).getAllItems()) { - result.computeIfAbsent(baseId(row.getDisplayId()), key -> new ArrayList<>()).add(row); + private List resolveSiblingRows(AppearancePatentResultRowDto representative, + Map> groupedRows) { + if (representative == null || groupedRows == null || groupedRows.isEmpty()) { + return List.of(); + } + String representativeKey = rowKey(representative.getId(), representative.getAsin(), representative.getCountry()); + for (List rows : groupedRows.values()) { + for (AppearancePatentParsedRowVo row : rows) { + String rowKey = rowKey(row.getDisplayId(), row.getAsin(), row.getCountry()); + if (Objects.equals(representativeKey, rowKey)) { + return rows; + } } + } + return List.of(); + } + + private Map> loadAllRowsByBaseId(FileTaskEntity task) { + try { + return groupRowsByBaseId(readParsedPayload(task).getAllItems()); } catch (Exception ex) { log.warn("[appearance-patent] read all rows failed taskId={} err={}", task.getId(), ex.getMessage()); + return new LinkedHashMap<>(); + } + } + + private Map> groupRowsByBaseId(List rows) { + Map> result = new LinkedHashMap<>(); + if (rows == null) { + return result; + } + for (AppearancePatentParsedRowVo row : rows) { + String key = firstNonBlank(normalize(row.getGroupKey()), baseId(row.getDisplayId())); + result.computeIfAbsent(key, ignored -> new ArrayList<>()).add(row); } return result; } @@ -517,8 +756,8 @@ public class AppearancePatentTaskService { row.setId(sibling.getDisplayId()); row.setAsin(sibling.getAsin()); row.setCountry(sibling.getCountry()); - row.setUrl(sibling.getUrl()); - row.setTitle(sibling.getTitle()); + row.setUrl(firstNonBlank(representative.getUrl(), sibling.getUrl())); + row.setTitle(firstNonBlank(representative.getTitle(), sibling.getTitle())); row.setError(representative.getError()); row.setTitleRisk(representative.getTitleRisk()); row.setAppearanceRisk(representative.getAppearanceRisk()); @@ -644,22 +883,7 @@ public class AppearancePatentTaskService { .eq(TaskChunkEntity::getModuleType, MODULE_TYPE) .orderByAsc(TaskChunkEntity::getChunkIndex)); for (TaskChunkEntity chunk : chunks) { - if (chunk.getPayloadJson() == null || chunk.getPayloadJson().isBlank()) { - continue; - } - try { - String payloadJson = transientPayloadStorageService.resolvePayload(chunk.getPayloadJson(), "read appearance patent chunk failed"); - JsonNode array = objectMapper.readTree(payloadJson); - if (!array.isArray()) { - continue; - } - for (JsonNode node : array) { - AppearancePatentResultRowDto row = objectMapper.treeToValue(node, AppearancePatentResultRowDto.class); - result.put(rowKey(row.getId(), row.getAsin(), row.getCountry()), row); - } - } catch (Exception ex) { - log.warn("[appearance-patent] read chunk payload failed taskId={} chunk={} err={}", taskId, chunk.getChunkIndex(), ex.getMessage()); - } + result.putAll(readChunkRows(chunk)); } return result; } @@ -672,26 +896,35 @@ public class AppearancePatentTaskService { font.setBold(true); headerStyle.setFont(font); + List resultHeaders = new ArrayList<>(RESULT_HEADERS); + resultHeaders.add(4, "title"); + resultHeaders.add(5, "url"); Row header = sheet.createRow(0); - for (int i = 0; i < RESULT_HEADERS.size(); i++) { + for (int i = 0; i < resultHeaders.size(); i++) { Cell cell = header.createCell(i); - cell.setCellValue(RESULT_HEADERS.get(i)); + cell.setCellValue(resultHeaders.get(i)); cell.setCellStyle(headerStyle); } int rowIndex = 1; for (AppearancePatentParsedRowVo parsedRow : parsed.getAllItems()) { AppearancePatentResultRowDto resultRow = resultMap.get(rowKey(parsedRow.getDisplayId(), parsedRow.getAsin(), parsedRow.getCountry())); + String missingReason = ""; + if (resultRow == null) { + missingReason = hasPromptFields(parsedRow) ? "未匹配到检测结果" : "未送检:缺少标题或图片"; + } Row row = sheet.createRow(rowIndex++); int col = 0; row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getDisplayId(), parsedRow.getSourceId())); row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getAsin(), "")); row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getCountry(), "")); row.createCell(col++).setCellValue(readValueByHeader(parsedRow, "价格", "price")); - row.createCell(col++).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getTitleRisk(), "")); - row.createCell(col++).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getAppearanceRisk(), "")); - row.createCell(col++).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getPatentRisk(), "")); - row.createCell(col).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getConclusion(), "")); + row.createCell(col++).setCellValue(resultRow == null ? firstNonBlank(parsedRow.getTitle(), "") : firstNonBlank(resultRow.getTitle(), parsedRow.getTitle())); + row.createCell(col++).setCellValue(resultRow == null ? firstNonBlank(parsedRow.getUrl(), "") : firstNonBlank(resultRow.getUrl(), parsedRow.getUrl())); + row.createCell(col++).setCellValue(resultRow == null ? missingReason : firstNonBlank(resultRow.getTitleRisk(), "")); + row.createCell(col++).setCellValue(resultRow == null ? missingReason : firstNonBlank(resultRow.getAppearanceRisk(), "")); + row.createCell(col++).setCellValue(resultRow == null ? missingReason : firstNonBlank(resultRow.getPatentRisk(), "")); + row.createCell(col).setCellValue(resultRow == null ? "未送检" : firstNonBlank(resultRow.getConclusion(), "")); } workbook.write(fos); workbook.dispose(); @@ -713,13 +946,18 @@ public class AppearancePatentTaskService { int idCol = findRequiredHeader(headerMap, "id"); int asinCol = findRequiredHeader(headerMap, "asin"); int countryCol = findRequiredHeader(headerMap, "国家", "country"); - int urlCol = findOptionalHeader(headerMap, "url", "rul", "链接", "商品链接"); - int titleCol = findOptionalHeader(headerMap, "标题", "title", "商品标题"); + int urlCol = findOptionalHeaderExact(headerMap, + "url", "rul", "link", "image", "img", "pic", "picture", + "链接", "商品链接", "图片", "商品图片", "主图", "商品主图", "图片链接", "主图链接"); + int titleCol = findOptionalHeaderExact(headerMap, + "标题", "title", "listing title", "product title", "商品标题", "商品名称", "产品名称"); List accepted = new ArrayList<>(); List allRows = new ArrayList<>(); int total = 0; int dropped = 0; + String currentBlockBaseId = ""; + String currentGroupKey = ""; for (int i = 1; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); if (row == null) { @@ -740,6 +978,12 @@ public class AppearancePatentTaskService { vo.setRowIndex(i + 1); vo.setSourceId(id); vo.setDisplayId(normalizeDisplayId(id)); + String rowBaseId = baseId(vo.getDisplayId()); + if (!Objects.equals(currentBlockBaseId, rowBaseId)) { + currentBlockBaseId = rowBaseId; + currentGroupKey = rowBaseId + "@" + vo.getRowIndex(); + } + vo.setGroupKey(currentGroupKey); vo.setAsin(asin); vo.setCountry(country); vo.setUrl(urlCol >= 0 ? cell(row, urlCol, formatter) : ""); @@ -752,6 +996,10 @@ public class AppearancePatentTaskService { dropped++; } } + hydratePromptFields(allRows); + if (accepted.isEmpty()) { + throw new BusinessException("no valid appearance patent rows"); + } return new ParsedWorkbook(total, dropped, headers, accepted, allRows); } catch (BusinessException ex) { throw ex; @@ -761,6 +1009,33 @@ public class AppearancePatentTaskService { } } + private void hydratePromptFields(List rows) { + if (rows == null || rows.isEmpty()) { + return; + } + Map> rowsByBaseId = groupRowsByBaseId(rows); + for (List siblings : rowsByBaseId.values()) { + String title = ""; + String url = ""; + for (AppearancePatentParsedRowVo sibling : siblings) { + title = firstNonBlank(title, sibling.getTitle()); + url = firstNonBlank(url, sibling.getUrl()); + } + for (AppearancePatentParsedRowVo sibling : siblings) { + if (normalize(sibling.getTitle()).isBlank()) { + sibling.setTitle(title); + } + if (normalize(sibling.getUrl()).isBlank()) { + sibling.setUrl(url); + } + } + } + } + + private boolean hasPromptFields(AppearancePatentParsedRowVo row) { + return row != null && (!normalize(row.getTitle()).isBlank() || !normalize(row.getUrl()).isBlank()); + } + private Map buildHeaderMap(Row header, DataFormatter formatter) { Map map = new LinkedHashMap<>(); for (int i = 0; i < header.getLastCellNum(); i++) { @@ -808,6 +1083,23 @@ public class AppearancePatentTaskService { return -1; } + private int findOptionalHeaderExact(Map map, String... names) { + for (Map.Entry entry : map.entrySet()) { + String normalizedHeader = normalizeHeaderAlias(entry.getKey()); + for (String name : names) { + if (normalizedHeader.equals(normalizeHeaderAlias(name))) { + return entry.getValue(); + } + } + } + return -1; + } + + private String normalizeHeaderAlias(String value) { + String normalized = normalize(value).toLowerCase(Locale.ROOT); + return normalized.replaceAll("[\\s_\\-()()\\[\\]{}::/\\\\]+", ""); + } + private String cell(Row row, int col, DataFormatter formatter) { return col < 0 ? "" : normalize(formatter.formatCellValue(row.getCell(col))); } @@ -933,6 +1225,28 @@ public class AppearancePatentTaskService { return new AppearancePatentParsedPayloadDto(); } + private Map readChunkRows(TaskChunkEntity chunk) { + Map rows = new LinkedHashMap<>(); + if (chunk == null || chunk.getPayloadJson() == null || chunk.getPayloadJson().isBlank()) { + return rows; + } + try { + String payloadJson = transientPayloadStorageService.resolvePayload(chunk.getPayloadJson(), "read appearance patent chunk failed"); + JsonNode array = objectMapper.readTree(payloadJson); + if (!array.isArray()) { + return rows; + } + for (JsonNode node : array) { + AppearancePatentResultRowDto row = objectMapper.treeToValue(node, AppearancePatentResultRowDto.class); + rows.put(rowKey(row.getId(), row.getAsin(), row.getCountry()), row); + } + } catch (Exception ex) { + log.warn("[appearance-patent] read chunk payload failed taskId={} chunk={} err={}", + chunk.getTaskId(), chunk.getChunkIndex(), ex.getMessage()); + } + return rows; + } + private String rowKey(String id, String asin, String country) { return normalize(id) + "::" + normalize(asin).toUpperCase(Locale.ROOT) + "::" + normalize(country); } @@ -996,6 +1310,13 @@ public class AppearancePatentTaskService { } } + private record SubmitContext(FileTaskEntity task, + String scopeKey, + String scopeHash, + boolean forceFlush, + String error) { + } + private record ParsedWorkbook(int totalRows, int droppedRows, List headers, List acceptedRows, List allRows) { } } diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/deletebrand/service/DeleteBrandStaleTaskService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/deletebrand/service/DeleteBrandStaleTaskService.java index d47ecba..50ee53c 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/deletebrand/service/DeleteBrandStaleTaskService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/deletebrand/service/DeleteBrandStaleTaskService.java @@ -27,7 +27,6 @@ import java.nio.file.attribute.FileTime; import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; -import java.time.ZoneId; import java.util.List; import java.util.Map; @@ -47,6 +46,7 @@ public class DeleteBrandStaleTaskService { private final FileTaskMapper fileTaskMapper; private final DeleteBrandTaskCacheService deleteBrandTaskCacheService; + private final DeleteBrandTaskStorageService deleteBrandTaskStorageService; private final DeleteBrandRunService deleteBrandRunService; private final ProductRiskTaskService productRiskTaskService; private final ProductRiskTaskCacheService productRiskTaskCacheService; @@ -110,7 +110,13 @@ public class DeleteBrandStaleTaskService { } private void failStaleDeleteBrandTasks() { - LocalDateTime threshold = LocalDateTime.now().minusMinutes(deleteBrandProgressProperties.getHeartbeatTimeoutMinutes()); + long minutes = Math.max(1L, deleteBrandProgressProperties.getHeartbeatTimeoutMinutes()); + long initialMinutes = Math.max(minutes, deleteBrandProgressProperties.getDeleteBrandInitialTimeoutMinutes()); + long staleTimeoutMillis = Duration.ofMinutes(minutes).toMillis(); + long nowMillis = System.currentTimeMillis(); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime threshold = now.minusMinutes(minutes); + LocalDateTime initialThreshold = now.minusMinutes(initialMinutes); java.util.List runningTasks = fileTaskMapper.selectList(new LambdaQueryWrapper() .eq(FileTaskEntity::getModuleType, MODULE_TYPE_DELETE_BRAND) @@ -120,36 +126,35 @@ public class DeleteBrandStaleTaskService { for (FileTaskEntity task : runningTasks) { Map progress = deleteBrandTaskCacheService.getProgress(task.getId()); - boolean hasProgress = progress != null && !progress.isEmpty() && progress.containsKey("last_heartbeat_at"); - - boolean isActive = false; - if (progress != null && progress.containsKey("has_progress")) { - Object hpObj = progress.get("has_progress"); - if (hpObj instanceof Boolean) { - isActive = (Boolean) hpObj; - } else if (hpObj instanceof String) { - isActive = Boolean.parseBoolean((String) hpObj); - } - } - long lastHeartbeatAt = 0L; - if (hasProgress) { + if (progress != null && !progress.isEmpty() && progress.containsKey("last_heartbeat_at")) { try { lastHeartbeatAt = Long.parseLong(String.valueOf(progress.get("last_heartbeat_at"))); } catch (Exception ignored) { } } + boolean hasStartedProgress = lastHeartbeatAt > 0L; + if (!hasStartedProgress) { + hasStartedProgress = deleteBrandTaskStorageService.countCompletedScopes(task.getId()) > 0 + || deleteBrandTaskStorageService.countParsedPayloadScopes(task.getId()) > 0; + } - if (lastHeartbeatAt > 0 && isActive) { - LocalDateTime lastActivityTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastHeartbeatAt), ZoneId.systemDefault()); - if (lastActivityTime.isAfter(threshold)) { - continue; - } - } else { - LocalDateTime queuedThreshold = LocalDateTime.now().minusHours(12); - if (task.getCreatedAt() != null && task.getCreatedAt().isAfter(queuedThreshold)) { + if (lastHeartbeatAt > 0L && nowMillis - lastHeartbeatAt < staleTimeoutMillis) { + continue; + } + if (!hasStartedProgress && task.getCreatedAt() != null && task.getCreatedAt().isAfter(initialThreshold)) { + continue; + } + + try { + deleteBrandRunService.tryFinalizeTask(task.getId(), true); + FileTaskEntity refreshed = fileTaskMapper.selectById(task.getId()); + if (refreshed != null && !"RUNNING".equals(refreshed.getStatus())) { + deleteBrandTaskCacheService.saveTaskCache(refreshed); continue; } + } catch (Exception ex) { + log.warn("[stale-check] delete-brand finalize threw taskId={} msg={}", task.getId(), ex.getMessage()); } int updated = fileTaskMapper.update(null, new LambdaUpdateWrapper() diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java index d8387ca..21298b0 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/patroldelete/service/PatrolDeleteTaskService.java @@ -49,6 +49,9 @@ public class PatrolDeleteTaskService { private static final String MODULE_TYPE = "PATROL_DELETE"; private static final String CONTENT_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + private static final int RESULT_PENDING = -1; + private static final int RESULT_FAILED = 0; + private static final int RESULT_SUCCESS = 1; private static final String INTERRUPTED_MESSAGE = "Python 在该店铺结果提交完成前中断"; private final FileTaskMapper fileTaskMapper; @@ -264,12 +267,13 @@ public class PatrolDeleteTaskService { result.setSourceFilename(normalizedShopName); result.setSourceFileUrl(item.getShopId()); result.setUserId(request.getUserId()); - result.setSuccess(null); + result.setSuccess(RESULT_PENDING); result.setCreatedAt(now); fileResultMapper.insert(result); snapshots.add(toSnapshotVo(result, item, task.getStatus(), null)); } persistTaskJson(task, uniqueItems, snapshots); + taskCacheService.saveTaskCache(task); PatrolDeleteCreateTaskVo vo = new PatrolDeleteCreateTaskVo(); vo.setTaskId(task.getId()); @@ -326,6 +330,7 @@ public class PatrolDeleteTaskService { persistSnapshotJson(task, snapshots); fileTaskMapper.updateById(task); + taskCacheService.saveTaskCache(task); tryFinalizeTask(taskId, false); } @@ -402,6 +407,7 @@ public class PatrolDeleteTaskService { persistSnapshotJson(task, snapshots); fileTaskMapper.updateById(task); + taskCacheService.saveTaskCache(task); return changed; } @@ -448,6 +454,7 @@ public class PatrolDeleteTaskService { updateTaskStatusFromRows(task, rows); persistSnapshotJson(task, buildSnapshotFromDb(task, rows)); fileTaskMapper.updateById(task); + taskCacheService.saveTaskCache(task); } private long countTasks(Long userId, List statuses) { @@ -502,9 +509,9 @@ public class PatrolDeleteTaskService { private Map> buildSnapshotMap(Map taskMap) { Map> out = new LinkedHashMap<>(); for (Map.Entry entry : taskMap.entrySet()) { - List snapshots = taskResultItemService.listResultSnapshots(entry.getKey(), MODULE_TYPE, PatrolDeleteResultItemVo.class); + List snapshots = parseTaskSnapshots(entry.getValue().getResultJson()); if (snapshots.isEmpty()) { - snapshots = parseTaskSnapshots(entry.getValue().getResultJson()); + snapshots = taskResultItemService.listResultSnapshots(entry.getKey(), MODULE_TYPE, PatrolDeleteResultItemVo.class); } out.put(entry.getKey(), indexSnapshotByResultId(snapshots)); } @@ -518,7 +525,7 @@ public class PatrolDeleteTaskService { item.setShopName(firstNonBlank(item.getShopName(), entity.getSourceFilename())); item.setShopId(firstNonBlank(item.getShopId(), entity.getSourceFileUrl())); item.setTaskStatus(task != null ? task.getStatus() : item.getTaskStatus()); - item.setSuccess(entity.getSuccess() == null ? item.getSuccess() : entity.getSuccess() == 1); + item.setSuccess(toSuccessFlag(entity.getSuccess(), item.getSuccess())); item.setError(!blank(entity.getErrorMessage()) ? entity.getErrorMessage() : item.getError()); item.setCreatedAt(entity.getCreatedAt()); item.setFinishedAt(task != null ? task.getFinishedAt() : item.getFinishedAt()); @@ -575,7 +582,7 @@ public class PatrolDeleteTaskService { vo.setMatchStatus(item.getMatchStatus()); vo.setMatchMessage(item.getMatchMessage()); vo.setTaskStatus(taskStatus); - vo.setSuccess(result.getSuccess() == null ? null : result.getSuccess() == 1); + vo.setSuccess(toSuccessFlag(result.getSuccess(), null)); vo.setError(result.getErrorMessage()); vo.setCreatedAt(result.getCreatedAt()); vo.setFinishedAt(finishedAt); @@ -616,7 +623,7 @@ public class PatrolDeleteTaskService { item.setShopName(row.getSourceFilename()); item.setShopId(row.getSourceFileUrl()); item.setTaskStatus(task == null ? null : task.getStatus()); - item.setSuccess(row.getSuccess() == null ? null : row.getSuccess() == 1); + item.setSuccess(toSuccessFlag(row.getSuccess(), null)); item.setError(row.getErrorMessage()); item.setCreatedAt(row.getCreatedAt()); item.setFinishedAt(task == null ? null : task.getFinishedAt()); @@ -642,8 +649,8 @@ public class PatrolDeleteTaskService { } private void updateTaskStatusFromRows(FileTaskEntity task, List rows) { - long successCount = rows.stream().filter(row -> Integer.valueOf(1).equals(row.getSuccess())).count(); - long failedCount = rows.stream().filter(row -> Integer.valueOf(0).equals(row.getSuccess())).count(); + long successCount = rows.stream().filter(row -> Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess())).count(); + long failedCount = rows.stream().filter(row -> Integer.valueOf(RESULT_FAILED).equals(row.getSuccess())).count(); long pendingCount = rows.stream().filter(row -> !isResultFinished(row)).count(); task.setSuccessFileCount((int) successCount); task.setFailedFileCount((int) failedCount); @@ -796,11 +803,11 @@ public class PatrolDeleteTaskService { .filter(item -> Boolean.TRUE.equals(item.getSuccess())) .toList(); if (!successItems.isEmpty()) { - String filename = safeFileStem("patrol-delete-" + task.getId()) + ".xlsx"; + String filename = buildTaskWorkbookFilename(task); int rowCount = excelAssemblyService.countRows(successItems); FileResultEntity firstSuccessRow = null; for (FileResultEntity row : rows) { - if (Integer.valueOf(1).equals(row.getSuccess())) { + if (Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess())) { row.setResultFilename(filename); row.setResultFileUrl(null); row.setResultFileSize(0L); @@ -843,7 +850,7 @@ public class PatrolDeleteTaskService { throw new BusinessException("没有可生成的巡店删除结果"); } File workRoot = FileUtil.mkdir(FileUtil.file(System.getProperty("java.io.tmpdir"), "patrol-delete-result", String.valueOf(task.getId()))); - String filename = safeFileStem("patrol-delete-" + task.getId()) + ".xlsx"; + String filename = buildTaskWorkbookFilename(task); File xlsx = FileUtil.file(workRoot, filename); try { excelAssemblyService.writeWorkbook(xlsx, successItems); @@ -851,7 +858,7 @@ public class PatrolDeleteTaskService { long fileSize = xlsx.length(); int rowCount = excelAssemblyService.countRows(successItems); for (FileResultEntity row : rows) { - if (Integer.valueOf(1).equals(row.getSuccess())) { + if (Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess())) { row.setResultFilename(filename); row.setResultFileUrl(objectKey); row.setResultFileSize(fileSize); @@ -866,13 +873,13 @@ public class PatrolDeleteTaskService { } private void markResultSuccess(FileResultEntity row) { - row.setSuccess(1); + row.setSuccess(RESULT_SUCCESS); row.setErrorMessage(null); fileResultMapper.updateById(row); } private void markResultFailed(FileResultEntity row, String message) { - row.setSuccess(0); + row.setSuccess(RESULT_FAILED); row.setErrorMessage(blankToNull(message)); row.setResultFilename(null); row.setResultFileUrl(null); @@ -883,7 +890,14 @@ public class PatrolDeleteTaskService { } private boolean isResultFinished(FileResultEntity row) { - return Integer.valueOf(1).equals(row.getSuccess()) || Integer.valueOf(0).equals(row.getSuccess()); + return Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess()) || Integer.valueOf(RESULT_FAILED).equals(row.getSuccess()); + } + + private Boolean toSuccessFlag(Integer dbValue, Boolean fallback) { + if (dbValue == null || Integer.valueOf(RESULT_PENDING).equals(dbValue)) { + return fallback; + } + return Integer.valueOf(RESULT_SUCCESS).equals(dbValue); } private List parseTaskSnapshots(String json) { @@ -972,6 +986,11 @@ public class PatrolDeleteTaskService { return !blank(first) ? first : second; } + private String buildTaskWorkbookFilename(FileTaskEntity task) { + Long taskId = task == null ? null : task.getId(); + return safeFileStem("巡店删除-" + (taskId == null ? "result" : taskId)) + ".xlsx"; + } + private String safeFileStem(String value) { String raw = value == null ? "result" : value.trim(); String safe = raw.replaceAll("[\\\\/:*?\"<>|]+", "_"); diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/queryasin/service/QueryAsinTaskService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/queryasin/service/QueryAsinTaskService.java index 344a744..b266054 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/queryasin/service/QueryAsinTaskService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/queryasin/service/QueryAsinTaskService.java @@ -49,6 +49,9 @@ public class QueryAsinTaskService { private static final String MODULE_TYPE = "QUERY_ASIN"; private static final String CONTENT_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + private static final int RESULT_PENDING = -1; + private static final int RESULT_FAILED = 0; + private static final int RESULT_SUCCESS = 1; private static final String INTERRUPTED_MESSAGE = "Python 在该店铺结果提交完成前中断"; private final FileTaskMapper fileTaskMapper; @@ -270,12 +273,13 @@ public class QueryAsinTaskService { result.setSourceFilename(normalizedShopName); result.setSourceFileUrl(item.getShopId()); result.setUserId(request.getUserId()); - result.setSuccess(null); + result.setSuccess(RESULT_PENDING); result.setCreatedAt(now); fileResultMapper.insert(result); snapshots.add(toSnapshotVo(result, item, task.getStatus(), null)); } persistTaskJson(task, uniqueItems, snapshots); + taskCacheService.saveTaskCache(task); QueryAsinCreateTaskVo vo = new QueryAsinCreateTaskVo(); vo.setTaskId(task.getId()); @@ -332,6 +336,7 @@ public class QueryAsinTaskService { persistSnapshotJson(task, snapshots); fileTaskMapper.updateById(task); + taskCacheService.saveTaskCache(task); tryFinalizeTask(taskId, false); } @@ -408,6 +413,7 @@ public class QueryAsinTaskService { persistSnapshotJson(task, snapshots); fileTaskMapper.updateById(task); + taskCacheService.saveTaskCache(task); return changed; } @@ -454,6 +460,7 @@ public class QueryAsinTaskService { updateTaskStatusFromRows(task, rows); persistSnapshotJson(task, buildSnapshotFromDb(task, rows)); fileTaskMapper.updateById(task); + taskCacheService.saveTaskCache(task); } private long countTasks(Long userId, List statuses) { @@ -508,9 +515,9 @@ public class QueryAsinTaskService { private Map> buildSnapshotMap(Map taskMap) { Map> out = new LinkedHashMap<>(); for (Map.Entry entry : taskMap.entrySet()) { - List snapshots = taskResultItemService.listResultSnapshots(entry.getKey(), MODULE_TYPE, QueryAsinResultItemVo.class); + List snapshots = parseTaskSnapshots(entry.getValue().getResultJson()); if (snapshots.isEmpty()) { - snapshots = parseTaskSnapshots(entry.getValue().getResultJson()); + snapshots = taskResultItemService.listResultSnapshots(entry.getKey(), MODULE_TYPE, QueryAsinResultItemVo.class); } out.put(entry.getKey(), indexSnapshotByResultId(snapshots)); } @@ -524,7 +531,7 @@ public class QueryAsinTaskService { item.setShopName(firstNonBlank(item.getShopName(), entity.getSourceFilename())); item.setShopId(firstNonBlank(item.getShopId(), entity.getSourceFileUrl())); item.setTaskStatus(task != null ? task.getStatus() : item.getTaskStatus()); - item.setSuccess(entity.getSuccess() == null ? item.getSuccess() : entity.getSuccess() == 1); + item.setSuccess(toSuccessFlag(entity.getSuccess(), item.getSuccess())); item.setError(!blank(entity.getErrorMessage()) ? entity.getErrorMessage() : item.getError()); item.setCreatedAt(entity.getCreatedAt()); item.setFinishedAt(task != null ? task.getFinishedAt() : item.getFinishedAt()); @@ -581,7 +588,7 @@ public class QueryAsinTaskService { vo.setMatchStatus(item.getMatchStatus()); vo.setMatchMessage(item.getMatchMessage()); vo.setTaskStatus(taskStatus); - vo.setSuccess(result.getSuccess() == null ? null : result.getSuccess() == 1); + vo.setSuccess(toSuccessFlag(result.getSuccess(), null)); vo.setError(result.getErrorMessage()); vo.setCreatedAt(result.getCreatedAt()); vo.setFinishedAt(finishedAt); @@ -622,7 +629,7 @@ public class QueryAsinTaskService { item.setShopName(row.getSourceFilename()); item.setShopId(row.getSourceFileUrl()); item.setTaskStatus(task == null ? null : task.getStatus()); - item.setSuccess(row.getSuccess() == null ? null : row.getSuccess() == 1); + item.setSuccess(toSuccessFlag(row.getSuccess(), null)); item.setError(row.getErrorMessage()); item.setCreatedAt(row.getCreatedAt()); item.setFinishedAt(task == null ? null : task.getFinishedAt()); @@ -648,8 +655,8 @@ public class QueryAsinTaskService { } private void updateTaskStatusFromRows(FileTaskEntity task, List rows) { - long successCount = rows.stream().filter(row -> Integer.valueOf(1).equals(row.getSuccess())).count(); - long failedCount = rows.stream().filter(row -> Integer.valueOf(0).equals(row.getSuccess())).count(); + long successCount = rows.stream().filter(row -> Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess())).count(); + long failedCount = rows.stream().filter(row -> Integer.valueOf(RESULT_FAILED).equals(row.getSuccess())).count(); long pendingCount = rows.stream().filter(row -> !isResultFinished(row)).count(); task.setSuccessFileCount((int) successCount); task.setFailedFileCount((int) failedCount); @@ -816,11 +823,11 @@ public class QueryAsinTaskService { .filter(item -> Boolean.TRUE.equals(item.getSuccess())) .toList(); if (!successItems.isEmpty()) { - String filename = safeFileStem("query-asin-" + task.getId()) + ".xlsx"; + String filename = buildTaskWorkbookFilename(task); int rowCount = excelAssemblyService.countRows(successItems); FileResultEntity firstSuccessRow = null; for (FileResultEntity row : rows) { - if (Integer.valueOf(1).equals(row.getSuccess())) { + if (Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess())) { row.setResultFilename(filename); row.setResultFileUrl(null); row.setResultFileSize(0L); @@ -863,7 +870,7 @@ public class QueryAsinTaskService { throw new BusinessException("没有可生成的查询ASIN结果"); } File workRoot = FileUtil.mkdir(FileUtil.file(System.getProperty("java.io.tmpdir"), "query-asin-result", String.valueOf(task.getId()))); - String filename = safeFileStem("query-asin-" + task.getId()) + ".xlsx"; + String filename = buildTaskWorkbookFilename(task); File xlsx = FileUtil.file(workRoot, filename); try { excelAssemblyService.writeWorkbook(xlsx, successItems); @@ -871,7 +878,7 @@ public class QueryAsinTaskService { long fileSize = xlsx.length(); int rowCount = excelAssemblyService.countRows(successItems); for (FileResultEntity row : rows) { - if (Integer.valueOf(1).equals(row.getSuccess())) { + if (Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess())) { row.setResultFilename(filename); row.setResultFileUrl(objectKey); row.setResultFileSize(fileSize); @@ -886,13 +893,13 @@ public class QueryAsinTaskService { } private void markResultSuccess(FileResultEntity row) { - row.setSuccess(1); + row.setSuccess(RESULT_SUCCESS); row.setErrorMessage(null); fileResultMapper.updateById(row); } private void markResultFailed(FileResultEntity row, String message) { - row.setSuccess(0); + row.setSuccess(RESULT_FAILED); row.setErrorMessage(blankToNull(message)); row.setResultFilename(null); row.setResultFileUrl(null); @@ -903,7 +910,14 @@ public class QueryAsinTaskService { } private boolean isResultFinished(FileResultEntity row) { - return Integer.valueOf(1).equals(row.getSuccess()) || Integer.valueOf(0).equals(row.getSuccess()); + return Integer.valueOf(RESULT_SUCCESS).equals(row.getSuccess()) || Integer.valueOf(RESULT_FAILED).equals(row.getSuccess()); + } + + private Boolean toSuccessFlag(Integer dbValue, Boolean fallback) { + if (dbValue == null || Integer.valueOf(RESULT_PENDING).equals(dbValue)) { + return fallback; + } + return Integer.valueOf(RESULT_SUCCESS).equals(dbValue); } private List parseTaskSnapshots(String json) { @@ -1034,6 +1048,11 @@ public class QueryAsinTaskService { return asin == null ? "" : asin.trim().toUpperCase(); } + private String buildTaskWorkbookFilename(FileTaskEntity task) { + Long taskId = task == null ? null : task.getId(); + return safeFileStem("查询ASIN-" + (taskId == null ? "result" : taskId)) + ".xlsx"; + } + private String safeFileStem(String value) { String raw = value == null ? "result" : value.trim(); String safe = raw.replaceAll("[\\\\/:*?\"<>|]+", "_"); diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/shopkey/service/QueryAsinService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/shopkey/service/QueryAsinService.java index e8a39d7..2e89945 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/shopkey/service/QueryAsinService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/shopkey/service/QueryAsinService.java @@ -15,6 +15,7 @@ import com.nanri.aiimage.modules.shopkey.model.vo.QueryAsinItemVo; import com.nanri.aiimage.modules.shopkey.model.vo.QueryAsinPageVo; import com.nanri.aiimage.modules.shopkey.model.vo.ShopManageGroupItemVo; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -30,9 +31,11 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; @Service @RequiredArgsConstructor +@Slf4j public class QueryAsinService { private static final List SUPPORTED_COUNTRIES = List.of("DE", "UK", "FR", "IT", "ES"); @@ -364,13 +367,32 @@ public class QueryAsinService { } private String normalizeCountry(String country) { - String normalized = normalizeBlank(country).toUpperCase(Locale.ROOT); + String normalized = normalizeCountryAlias(country); if (!SUPPORTED_COUNTRIES.contains(normalized)) { throw new BusinessException("国家参数不支持: " + country); } return normalized; } + private String normalizeCountryAlias(String country) { + String normalized = normalizeBlank(country); + if (normalized.isEmpty()) { + return ""; + } + String upper = normalized.toUpperCase(Locale.ROOT); + if (SUPPORTED_COUNTRIES.contains(upper)) { + return upper; + } + return switch (normalizeHeaderKey(normalized)) { + case "\u5fb7\u56fd", "\u5fb7", "de", "germany", "german", "deutschland" -> "DE"; + case "\u82f1\u56fd", "\u82f1", "uk", "gb", "greatbritain", "britain", "unitedkingdom" -> "UK"; + case "\u6cd5\u56fd", "\u6cd5", "fr", "france", "french" -> "FR"; + case "\u610f\u5927\u5229", "\u610f", "it", "italy", "italian" -> "IT"; + case "\u897f\u73ed\u7259", "\u897f", "es", "spain", "spanish", "espana" -> "ES"; + default -> ""; + }; + } + private String normalizeAsin(String asin) { String normalized = normalizeRequired(asin, "ASIN 不能为空").toUpperCase(Locale.ROOT); if (normalized.length() > 64) { @@ -505,13 +527,19 @@ public class QueryAsinService { } } headerLoaded = true; - if (findGroupIndex() == null && (fallbackGroupId == null || fallbackGroupId <= 0)) { + Integer resolvedGroupIndex = resolveGroupHeaderIndex(); + Integer resolvedShopIndex = resolveShopHeaderIndex(); + boolean hasWideCountries = hasWideCountryColumns(); + boolean hasSingleCountryAsin = hasSingleCountryAsinColumns(); + log.info("[query-asin-import] headerMap={} normalizedKeys={} groupIndex={} shopIndex={} hasWideCountries={} hasSingleCountryAsin={}", + headerMap, headerIndexByKey.keySet(), resolvedGroupIndex, resolvedShopIndex, hasWideCountries, hasSingleCountryAsin); + if (resolvedGroupIndex == null && (fallbackGroupId == null || fallbackGroupId <= 0)) { throw new BusinessException("Excel 缺少分组列,请在页面选择分组或提供分组列"); } - if (findShopIndex() == null) { + if (resolvedShopIndex == null) { throw new BusinessException("Excel 缺少店铺名列"); } - if (SUPPORTED_COUNTRIES.stream().noneMatch(country -> findCountryIndex(country) != null)) { + if (!hasWideCountries && !hasSingleCountryAsin) { throw new BusinessException("Excel 至少需要包含一个国家 ASIN 列"); } } @@ -524,7 +552,7 @@ public class QueryAsinService { progress.setProcessedRows(rowIndex); Long groupId = resolveGroupId(rowMap); - String shopName = cell(rowMap, findShopIndex()); + String shopName = cell(rowMap, resolveShopHeaderIndex()); if (groupId == null || shopName.isEmpty()) { skippedCount++; updateProgress(); @@ -532,27 +560,8 @@ public class QueryAsinService { } QueryAsinEntity row = newImportEntity(groupId, shopName); - int rowAsinCount = 0; - int rowAcceptedCount = 0; - for (String country : SUPPORTED_COUNTRIES) { - Integer index = findCountryIndex(country); - if (index == null) { - continue; - } - String asin = normalizeBlank(cell(rowMap, index)).toUpperCase(Locale.ROOT); - if (asin.isEmpty()) { - continue; - } - if (asin.length() > 64) { - skippedCount++; - continue; - } - asinCount++; - rowAsinCount++; - setCountryAsin(row, country, asin); - rowAcceptedCount++; - } - if (rowAsinCount == 0) { + int rowAcceptedCount = collectRowCountryAsins(row, rowMap); + if (countCountryCells(row) == 0) { skippedCount++; } if (rowAcceptedCount > 0) { @@ -754,7 +763,7 @@ public class QueryAsinService { } private Long resolveGroupId(Map rowMap) { - Integer groupIndex = findGroupIndex(); + Integer groupIndex = resolveGroupHeaderIndex(); String groupText = cell(rowMap, groupIndex); if (groupText.isEmpty()) { return fallbackGroupId != null && fallbackGroupId > 0 ? fallbackGroupId : null; @@ -767,6 +776,51 @@ public class QueryAsinService { return id; } + private int collectRowCountryAsins(QueryAsinEntity row, Map rowMap) { + int acceptedCount = 0; + for (String country : SUPPORTED_COUNTRIES) { + Integer index = resolveCountryHeaderIndex(country); + if (index == null) { + continue; + } + acceptedCount += acceptCountryAsin(row, country, cell(rowMap, index)); + } + Integer singleCountryIndex = findSingleCountryIndex(); + Integer singleAsinIndex = findSingleAsinIndex(); + if (singleCountryIndex != null && singleAsinIndex != null) { + acceptedCount += acceptCountryAsin( + row, + normalizeCountryAlias(cell(rowMap, singleCountryIndex)), + cell(rowMap, singleAsinIndex)); + } + return acceptedCount; + } + + private int acceptCountryAsin(QueryAsinEntity row, String country, String asin) { + String normalizedAsin = normalizeBlank(asin).toUpperCase(Locale.ROOT); + if (normalizedAsin.isEmpty()) { + return 0; + } + asinCount++; + if (country == null || country.isEmpty() || !SUPPORTED_COUNTRIES.contains(country)) { + skippedCount++; + return 0; + } + if (normalizedAsin.length() > 64) { + skippedCount++; + return 0; + } + String existing = getCountryAsin(row, country); + if (!existing.isEmpty()) { + if (!existing.equals(normalizedAsin)) { + skippedCount++; + } + return 0; + } + setCountryAsin(row, country, normalizedAsin); + return 1; + } + private void loadGroups() { if (groupsLoaded) { return; @@ -801,6 +855,88 @@ public class QueryAsinService { }; } + private Integer resolveGroupHeaderIndex() { + Integer index = findGroupIndex(); + if (index != null) { + return index; + } + index = firstHeader("groupname", "\u5206\u7ec4id", "\u5206\u7ec4"); + if (index != null) { + return index; + } + return findHeaderByPredicate(key -> key.contains("\u5206\u7ec4") || key.contains("group")); + } + + private Integer resolveShopHeaderIndex() { + Integer index = findShopIndex(); + if (index != null) { + return index; + } + index = firstHeader( + "\u5e97\u94fa\u540d", "\u5e97\u94fa\u540d\u79f0", "\u5e97\u94fa\u8d26\u53f7", "\u8d26\u53f7", + "account", "selleraccount", "storeaccount", "storename"); + if (index != null) { + return index; + } + return findHeaderByPredicate(key -> + (key.contains("\u5e97\u94fa") && (key.contains("\u540d") || key.contains("\u8d26\u53f7"))) + || (key.contains("shop") && (key.contains("name") || key.contains("account"))) + || key.contains("selleraccount") + || key.contains("storeaccount")); + } + + private Integer resolveCountryHeaderIndex(String country) { + Integer index = findCountryIndex(country); + if (index != null) { + return index; + } + return switch (country) { + case "DE" -> firstHeader("\u5fb7\u56fd", "\u5fb7", "\u5fb7\u56fdasin"); + case "UK" -> firstHeader("\u82f1\u56fd", "\u82f1", "\u82f1\u56fdasin"); + case "FR" -> firstHeader("\u6cd5\u56fd", "\u6cd5", "\u6cd5\u56fdasin"); + case "IT" -> firstHeader("\u610f\u5927\u5229", "\u610f", "\u610f\u5927\u5229asin"); + case "ES" -> firstHeader("\u897f\u73ed\u7259", "\u897f", "\u897f\u73ed\u7259asin"); + default -> null; + }; + } + + private Integer findSingleCountryIndex() { + Integer index = firstHeader( + "\u4e2d\u6587\u56fd\u5bb6\u540d", "\u56fd\u5bb6", "\u56fd\u5bb6\u540d", "\u56fd\u5bb6\u7ad9\u70b9", + "\u7ad9\u70b9", "country", "countryname", "marketplace", "site"); + if (index != null) { + return index; + } + return findHeaderByPredicate(key -> + key.contains("\u56fd\u5bb6") + || key.contains("\u7ad9\u70b9") + || key.contains("country") + || key.contains("marketplace") + || key.equals("site")); + } + + private Integer findSingleAsinIndex() { + return firstHeader("asin", "\u67e5\u8be2asin", "\u4ea7\u54c1asin", "\u94fe\u63a5asin"); + } + + private boolean hasWideCountryColumns() { + return SUPPORTED_COUNTRIES.stream().anyMatch(country -> resolveCountryHeaderIndex(country) != null); + } + + private boolean hasSingleCountryAsinColumns() { + return findSingleCountryIndex() != null && findSingleAsinIndex() != null; + } + + private Integer findHeaderByPredicate(Predicate predicate) { + for (Map.Entry entry : headerIndexByKey.entrySet()) { + String key = entry.getKey(); + if (key != null && predicate.test(key)) { + return entry.getValue(); + } + } + return null; + } + private Integer firstHeader(String... names) { for (String name : names) { Integer index = headerIndexByKey.get(normalizeHeaderKey(name)); diff --git a/backend-java/src/main/java/com/nanri/aiimage/modules/task/service/TaskResultItemService.java b/backend-java/src/main/java/com/nanri/aiimage/modules/task/service/TaskResultItemService.java index 1b6f23f..d955967 100644 --- a/backend-java/src/main/java/com/nanri/aiimage/modules/task/service/TaskResultItemService.java +++ b/backend-java/src/main/java/com/nanri/aiimage/modules/task/service/TaskResultItemService.java @@ -125,15 +125,18 @@ public class TaskResultItemService { String status, Object payload) { String payloadJson = writeJson(payload); + String payloadHash = hash(payloadJson); String normalizedScopeKey = firstNonBlank(scopeKey, "task:" + taskId).trim(); String normalizedItemKey = firstNonBlank(itemKey, "result:" + resultId).trim(); String scopeHash = hash(normalizedScopeKey); - String storedPayload = transientPayloadStorageService.storeResultItemPayload( - moduleType, taskId, scopeHash, normalizedItemKey, payloadJson); - String payloadHash = hash(payloadJson); LocalDateTime now = LocalDateTime.now(); TaskResultItemEntity existing = find(taskId, moduleType, scopeHash, normalizedItemKey); + if (isUnchanged(existing, resultId, normalizedScopeKey, countryCode, asin, status, payloadHash)) { + return; + } + String storedPayload = transientPayloadStorageService.storeResultItemPayload( + moduleType, taskId, scopeHash, normalizedItemKey, payloadJson); if (existing == null) { TaskResultItemEntity entity = new TaskResultItemEntity(); entity.setTaskId(taskId); @@ -159,6 +162,10 @@ public class TaskResultItemService { if (existing == null) { throw new BusinessException("保存任务结果明细失败"); } + if (isUnchanged(existing, resultId, normalizedScopeKey, countryCode, asin, status, payloadHash)) { + transientPayloadStorageService.deleteReplacedPayloadIfNeeded(storedPayload, existing.getPayloadJson()); + return; + } transientPayloadStorageService.deleteReplacedPayloadIfNeeded(existing.getPayloadJson(), storedPayload); taskResultItemMapper.update(null, new LambdaUpdateWrapper() .eq(TaskResultItemEntity::getId, existing.getId()) @@ -172,6 +179,24 @@ public class TaskResultItemService { .set(TaskResultItemEntity::getUpdatedAt, now)); } + private boolean isUnchanged(TaskResultItemEntity existing, + Long resultId, + String scopeKey, + String countryCode, + String asin, + String status, + String payloadHash) { + if (existing == null) { + return false; + } + return java.util.Objects.equals(existing.getResultId(), resultId) + && java.util.Objects.equals(existing.getScopeKey(), scopeKey) + && java.util.Objects.equals(existing.getCountryCode(), countryCode) + && java.util.Objects.equals(existing.getAsin(), asin) + && java.util.Objects.equals(existing.getStatus(), status) + && java.util.Objects.equals(existing.getPayloadHash(), payloadHash); + } + private TaskResultItemEntity find(Long taskId, String moduleType, String scopeHash, String itemKey) { return taskResultItemMapper.selectOne(new LambdaQueryWrapper() .eq(TaskResultItemEntity::getTaskId, taskId) diff --git a/backend-java/src/main/resources/application-local.example.yml b/backend-java/src/main/resources/application-local.example.yml index 3c5db4e..f734238 100644 --- a/backend-java/src/main/resources/application-local.example.yml +++ b/backend-java/src/main/resources/application-local.example.yml @@ -31,6 +31,7 @@ AIIMAGE_APPEARANCE_PATENT_COZE_WORKFLOW_PATH=/v1/workflow/run AIIMAGE_APPEARANCE_PATENT_COZE_WORKFLOW_ID=7632683471312355338 AIIMAGE_APPEARANCE_PATENT_COZE_TOKEN= AIIMAGE_APPEARANCE_PATENT_COZE_BATCH_SIZE=10 +AIIMAGE_APPEARANCE_PATENT_COZE_READ_TIMEOUT_MILLIS=60000 AIIMAGE_APPEARANCE_PATENT_STALE_TIMEOUT_MINUTES=20 AIIMAGE_ROCKETMQ_NAME_SERVER=121.196.149.225:9876 diff --git a/backend-java/src/main/resources/application.yml b/backend-java/src/main/resources/application.yml index 1220fbd..481a12a 100644 --- a/backend-java/src/main/resources/application.yml +++ b/backend-java/src/main/resources/application.yml @@ -136,6 +136,8 @@ aiimage: coze-workflow-id: ${AIIMAGE_APPEARANCE_PATENT_COZE_WORKFLOW_ID:7632683471312355338} coze-token: ${AIIMAGE_APPEARANCE_PATENT_COZE_TOKEN:} coze-batch-size: ${AIIMAGE_APPEARANCE_PATENT_COZE_BATCH_SIZE:10} + coze-connect-timeout-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_CONNECT_TIMEOUT_MILLIS:10000} + coze-read-timeout-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_READ_TIMEOUT_MILLIS:60000} stale-timeout-minutes: ${AIIMAGE_APPEARANCE_PATENT_STALE_TIMEOUT_MINUTES:20} stale-finalize-cron: ${AIIMAGE_APPEARANCE_PATENT_STALE_FINALIZE_CRON:0 */2 * * * *} security: diff --git a/backend/__pycache__/config.cpython-312.pyc b/backend/__pycache__/config.cpython-312.pyc index 08477f7..82ec769 100644 Binary files a/backend/__pycache__/config.cpython-312.pyc and b/backend/__pycache__/config.cpython-312.pyc differ diff --git a/backend/config.py b/backend/config.py index 6692838..97a3eb7 100644 --- a/backend/config.py +++ b/backend/config.py @@ -23,8 +23,8 @@ bucket_path = "nanri-image/" file_url_pre = f"https://{bucket}.oss-cn-hangzhou.aliyuncs.com/" import os -# backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://127.0.0.1:18080').rstrip('/') -backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://8.136.19.173:18080').rstrip('/') +backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://127.0.0.1:18080').rstrip('/') +# backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://8.136.19.173:18080').rstrip('/') os.environ['OSS_ACCESS_KEY_ID'] = accessKeyId os.environ['OSS_ACCESS_KEY_SECRET'] = accessKeySecret os.environ['SECRET_KEY'] = "ddffc7c1d02121d9554d7b080b2511b6" diff --git a/backend/web_source/admin.html b/backend/web_source/admin.html index 6094daf..ccfb20b 100644 --- a/backend/web_source/admin.html +++ b/backend/web_source/admin.html @@ -862,7 +862,7 @@

导入添加

- +
@@ -879,7 +879,7 @@

导入删除

- +