From b96b136fa37d84fbbef5a1b1d2981e04fe58aa73 Mon Sep 17 00:00:00 2001 From: super <2903208875@qq.com> Date: Mon, 27 Apr 2026 18:45:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0rufts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/.env | 4 +- .../__pycache__/approve.cpython-312.pyc | Bin 55959 -> 56115 bytes .../__pycache__/asin_status.cpython-312.pyc | Bin 0 -> 32106 bytes .../__pycache__/detail_spider.cpython-312.pyc | Bin 0 -> 76500 bytes app/amazon/__pycache__/main.cpython-312.pyc | Bin 29925 -> 30167 bytes .../__pycache__/match_action.cpython-312.pyc | Bin 33733 -> 33840 bytes .../__pycache__/price_match.cpython-312.pyc | Bin 56585 -> 60648 bytes app/amazon/detail_spider.py | 26 +- backend-java/jstack-6488.txt | 1056 +++++++++++++++++ .../config/AppearancePatentProperties.java | 2 + .../config/DeleteBrandProgressProperties.java | 1 + .../client/AppearancePatentCozeClient.java | 271 ++++- .../model/vo/AppearancePatentParsedRowVo.java | 1 + .../AppearancePatentTaskCacheService.java | 8 +- .../service/AppearancePatentTaskService.java | 415 ++++++- .../service/DeleteBrandStaleTaskService.java | 51 +- .../service/PatrolDeleteTaskService.java | 49 +- .../service/QueryAsinTaskService.java | 49 +- .../shopkey/service/QueryAsinService.java | 190 ++- .../task/service/TaskResultItemService.java | 31 +- .../resources/application-local.example.yml | 1 + .../src/main/resources/application.yml | 2 + backend/__pycache__/config.cpython-312.pyc | Bin 1513 -> 1510 bytes backend/config.py | 4 +- backend/web_source/admin.html | 4 +- 25 files changed, 1992 insertions(+), 173 deletions(-) create mode 100644 app/amazon/__pycache__/asin_status.cpython-312.pyc create mode 100644 app/amazon/__pycache__/detail_spider.cpython-312.pyc create mode 100644 backend-java/jstack-6488.txt 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 859dd8ca81f1bf1dfed253f1acbccd2def5a0125..d4bc9b61336df6883e9c76277c68bc90b922598a 100644 GIT binary patch delta 821 zcmYjOX-HI26u##@U%XkKGtD?Yml;z>aVr;6T!PFB9WfyVBMC9}i6o-TbIgR9Ac+I((vNs;P#Dz9rM!Rc_nmvb@0^d@^_Z5P(A*Tq zsflvVKK*n~7~r1SxfOjtm%2mUeXvs}`$-G-vfbx{)_*O2c|65A4js3U4s3c#Gr1d+7hw7Pf`85=Y=x z7a>tZEO%*zAc3vZy3pPmqzZOwlr2IWp?Il}2Ll#%T7g4*rzLIIRzj#FbjQM}-LXGU zL`n#BsY{8#y0jOy?Q;Tq^Q8qtd?EC{O+!;0wL9Fu#^+mtW@siC=u*-QaS>9JZwMH1 zT^WN1`j4WcznE__C~ReTc(v``>ix@W?klUl_7B(GIM#m%bVvEb(#{QE@le>#RG^ojGkzoZg!> z$0o~u*d`T13@%A|;e*G9K+2slW-VDF+_}Gh$Qp)=-1rto^ub>UsIswdlE>mfV|tb; zk5FSYZ%ZKKL}iO*##K2co0XZcG76bUQ01HHiPW%so}T0x1&fi&Z;2_=?ZFc|Mod%) zet&h!kfeY(qi9yLZg*hW$Q?+=UnAj=DOpAt4Wvuf>BAJHVC8HLB;o5>GmJ`Wvo;Dc zFnPW}o2+;&`&BkH)QL%Wb>6o>7Z@Ad6=bprhElh|gmoKC3pHQ2-sF>5vG5bpq%(_) p;9sPI68KCuFS!oI%z^dCKp`quye delta 733 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

0xM5gxHlr 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 literal 0 HcmV?d00001 diff --git a/app/amazon/__pycache__/main.cpython-312.pyc b/app/amazon/__pycache__/main.cpython-312.pyc index a92e3b52a8d2a1915c4897f75ad7e0bd2893d995..d1560d000b31018d94d80262297ab0ecafd9a67e 100644 GIT binary patch delta 3593 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 o^AbCm_l)_*#J!i4=|;?pi^hDdLkw{PQPY^cN8- zV<=)u5v%2kWJuwt6{r*Fc{O>uza^tQP*PWTFGQ@Iv7DiTIg+8AQB!fVU_c;~c&QN3 z=qI~(KkZuhbV~>MuYBF<}v#vWk(@_&$4(#yeMosIWNpv*UgyesDiGCD8n&hP7fj0V>XUF9=xn4 fcv*p*6QZ1+Y|JO*7NiRRo^v+M diff --git a/app/amazon/__pycache__/price_match.cpython-312.pyc b/app/amazon/__pycache__/price_match.cpython-312.pyc index b3bad90cd09e40011ac40d539e473c12060d1c57..ec269ddc1fbfee7462e5e35dbdbcf6ef6b4abc1f 100644 GIT binary patch delta 16917 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 X&b@7#&M(a6->%A7n8E)s1M&Y0bYEM; 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 08477f7ce04a0e3486e7c30061df54b3d730c5f0..82ec76926cefc97105b15f4e706f3f129fb36ea6 100644 GIT binary patch delta 86 zcmaFK{fwLUG%qg~0}yaozt23mk@qW;pjbvpNr9EVzM+x1o&gXVZWdz>WKy{yAvK?C pCf9tvnS2-2?JhV(T$YHuE|G9iBH=<}%4Lbv3k;$UCU>*O0RVNq9Krwq delta 89 zcmaFH{gRvaG%qg~0}wKqi$3 t5>oTIW^&Evo5^=U-R^=z^ks>d>k`QqC6X_sq+gcExWFKKV{!*;901699j^cY 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 @@

导入删除

- +