sycommon-python-lib 0.1.36__tar.gz → 0.1.38__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/PKG-INFO +1 -1
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/pyproject.toml +1 -1
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/rabbitmq/rabbitmq_client.py +65 -45
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/rabbitmq/rabbitmq_service.py +24 -1
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/nacos_service.py +1 -1
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/README.md +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/setup.cfg +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/logging/kafka_log.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/traceid.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/services.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon_python_lib.egg-info/SOURCES.txt +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
- {sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/rabbitmq/rabbitmq_client.py
RENAMED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
from aio_pika.pool import Pool
|
|
2
|
+
from aio_pika.abc import AbstractRobustConnection
|
|
3
|
+
from aio_pika import connect_robust, Channel
|
|
4
|
+
from typing import Optional, List
|
|
1
5
|
import asyncio
|
|
2
6
|
import json
|
|
3
7
|
from typing import Callable, Coroutine, Optional, Dict, Any, Union, Set
|
|
@@ -81,9 +85,8 @@ class RabbitMQClient:
|
|
|
81
85
|
self._exchange_exists = False # 由 _connection_lock 保护
|
|
82
86
|
self._queue_exists = False # 由 _connection_lock 保护
|
|
83
87
|
self._queue_bound = False # 由 _connection_lock 保护
|
|
84
|
-
self._is_consuming = False # 由 _consume_state_lock 保护
|
|
85
88
|
self._closed = False # 由 _connection_lock 保护
|
|
86
|
-
# 由 _consume_state_lock
|
|
89
|
+
# 由 _consume_state_lock 保护:通过 consumer_tag 存在性判断是否在消费
|
|
87
90
|
self._consumer_tag: Optional[ConsumerTag] = None
|
|
88
91
|
self._last_activity_timestamp = asyncio.get_event_loop().time()
|
|
89
92
|
self._last_message_processed = asyncio.get_event_loop().time()
|
|
@@ -102,7 +105,7 @@ class RabbitMQClient:
|
|
|
102
105
|
self._tracking_messages: Dict[str, Dict[str, Any]] = {}
|
|
103
106
|
|
|
104
107
|
# 细粒度锁(核心设计:按资源类型拆分,避免嵌套)
|
|
105
|
-
# 保护消费状态(
|
|
108
|
+
# 保护消费状态(message_handler、_consumer_tag)
|
|
106
109
|
self._consume_state_lock = asyncio.Lock()
|
|
107
110
|
self._tracking_lock = asyncio.Lock() # 保护消息跟踪记录(_tracking_messages)
|
|
108
111
|
# 保护连接/资源状态(channel、exchange、queue、_closed等)
|
|
@@ -131,17 +134,19 @@ class RabbitMQClient:
|
|
|
131
134
|
async def _get_consume_state(self) -> tuple[bool, Optional[Callable], Optional[ConsumerTag]]:
|
|
132
135
|
"""安全获取消费相关状态(一次性获取,避免多次加锁)"""
|
|
133
136
|
async with self._consume_state_lock:
|
|
134
|
-
|
|
137
|
+
# 通过 _consumer_tag 是否存在判断是否在消费
|
|
138
|
+
is_consuming = self._consumer_tag is not None
|
|
139
|
+
return is_consuming, self.message_handler, self._consumer_tag
|
|
135
140
|
|
|
136
|
-
async def
|
|
137
|
-
"""
|
|
141
|
+
async def _set_consumer_tag(self, consumer_tag: Optional[ConsumerTag] = None):
|
|
142
|
+
"""安全更新消费者标签(替代原 _set_consume_state)"""
|
|
138
143
|
async with self._consume_state_lock:
|
|
139
|
-
|
|
140
|
-
self.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if old_is_consuming !=
|
|
144
|
-
logger.info(f"消费状态变更: {old_is_consuming} → {
|
|
144
|
+
old_tag = self._consumer_tag
|
|
145
|
+
self._consumer_tag = consumer_tag
|
|
146
|
+
old_is_consuming = old_tag is not None
|
|
147
|
+
new_is_consuming = consumer_tag is not None
|
|
148
|
+
if old_is_consuming != new_is_consuming:
|
|
149
|
+
logger.info(f"消费状态变更: {old_is_consuming} → {new_is_consuming}")
|
|
145
150
|
|
|
146
151
|
async def set_message_handler(self, handler):
|
|
147
152
|
"""设置消息处理器(加锁保护,避免并发修改)"""
|
|
@@ -332,7 +337,7 @@ class RabbitMQClient:
|
|
|
332
337
|
# 重置连接状态和跟踪记录
|
|
333
338
|
await self._reset_connection_state()
|
|
334
339
|
await self._clear_tracking_messages()
|
|
335
|
-
await self.
|
|
340
|
+
await self._set_consumer_tag(None) # 重置消费者标签(停止消费)
|
|
336
341
|
|
|
337
342
|
retries = 0
|
|
338
343
|
last_exception = None
|
|
@@ -401,9 +406,9 @@ class RabbitMQClient:
|
|
|
401
406
|
if not await self.is_connected:
|
|
402
407
|
raise Exception("连接验证失败,状态异常")
|
|
403
408
|
|
|
404
|
-
#
|
|
405
|
-
|
|
406
|
-
if handler:
|
|
409
|
+
# 重新开始消费(如果已设置处理器且之前在消费)
|
|
410
|
+
_, handler, consumer_tag = await self._get_consume_state()
|
|
411
|
+
if handler and consumer_tag: # 有处理器且之前有消费标签,说明需要恢复消费
|
|
407
412
|
await self.start_consuming()
|
|
408
413
|
|
|
409
414
|
# 启动监控和保活任务
|
|
@@ -411,6 +416,12 @@ class RabbitMQClient:
|
|
|
411
416
|
self._start_keepalive()
|
|
412
417
|
|
|
413
418
|
self._update_activity_timestamp()
|
|
419
|
+
|
|
420
|
+
# 首次启动时延迟1秒(避免初始化未完成就接收消息)
|
|
421
|
+
if not force_reconnect:
|
|
422
|
+
logger.info("客户端初始化成功,延迟1秒接收消息(解决启动时序问题)")
|
|
423
|
+
await asyncio.sleep(1)
|
|
424
|
+
|
|
414
425
|
logger.info(f"RabbitMQ客户端初始化成功 (队列: {self.actual_queue_name})")
|
|
415
426
|
return
|
|
416
427
|
|
|
@@ -447,9 +458,9 @@ class RabbitMQClient:
|
|
|
447
458
|
if cleaned_count > 0:
|
|
448
459
|
logger.info(f"清理了 {cleaned_count} 条已确认消息记录")
|
|
449
460
|
|
|
450
|
-
#
|
|
451
|
-
|
|
452
|
-
if
|
|
461
|
+
# 检查消费停滞(仅当有消费者标签时)
|
|
462
|
+
_, handler, consumer_tag = await self._get_consume_state()
|
|
463
|
+
if consumer_tag: # 有消费标签说明正在消费
|
|
453
464
|
tracking_count = await self._get_tracking_count()
|
|
454
465
|
if current_time - self._last_message_processed > self.consumption_stall_threshold:
|
|
455
466
|
if tracking_count > 0:
|
|
@@ -469,7 +480,7 @@ class RabbitMQClient:
|
|
|
469
480
|
except Exception as e:
|
|
470
481
|
logger.error(
|
|
471
482
|
f"重启消费失败: {str(e)}", exc_info=True)
|
|
472
|
-
await self.
|
|
483
|
+
await self._set_consumer_tag(None)
|
|
473
484
|
|
|
474
485
|
except Exception as e:
|
|
475
486
|
logger.error(f"监控任务出错: {str(e)}", exc_info=True)
|
|
@@ -482,7 +493,7 @@ class RabbitMQClient:
|
|
|
482
493
|
async def _recreate_channel(self) -> None:
|
|
483
494
|
"""重建通道并恢复资源(无锁嵌套)"""
|
|
484
495
|
# 先停止消费
|
|
485
|
-
await self.
|
|
496
|
+
await self._set_consumer_tag(None)
|
|
486
497
|
logger.info("开始重建通道...")
|
|
487
498
|
|
|
488
499
|
try:
|
|
@@ -505,7 +516,7 @@ class RabbitMQClient:
|
|
|
505
516
|
# 更新连接资源
|
|
506
517
|
await self._update_connection_resources(channel, exchange, queue)
|
|
507
518
|
|
|
508
|
-
#
|
|
519
|
+
# 重新开始消费(如果有处理器)
|
|
509
520
|
_, handler, _ = await self._get_consume_state()
|
|
510
521
|
if handler:
|
|
511
522
|
await self.start_consuming()
|
|
@@ -516,7 +527,7 @@ class RabbitMQClient:
|
|
|
516
527
|
self._update_activity_timestamp()
|
|
517
528
|
except Exception as e:
|
|
518
529
|
logger.error(f"通道重建失败: {str(e)},触发重连", exc_info=True)
|
|
519
|
-
await self.
|
|
530
|
+
await self._set_consumer_tag(None)
|
|
520
531
|
await self.connect(force_reconnect=True)
|
|
521
532
|
|
|
522
533
|
def _start_keepalive(self) -> None:
|
|
@@ -701,16 +712,29 @@ class RabbitMQClient:
|
|
|
701
712
|
if await self._is_closed():
|
|
702
713
|
raise Exception("客户端已关闭,无法启动消费")
|
|
703
714
|
|
|
704
|
-
#
|
|
715
|
+
# 检查连接状态(确保通道完全就绪)
|
|
705
716
|
if not await self.is_connected:
|
|
706
717
|
await self.connect()
|
|
707
718
|
|
|
719
|
+
# 确保通道未关闭(解决启动时通道初始化滞后问题)
|
|
720
|
+
channel, _, _ = await self._get_connection_resources()
|
|
721
|
+
max_wait_attempts = 5
|
|
722
|
+
wait_interval = 0.5
|
|
723
|
+
for attempt in range(max_wait_attempts):
|
|
724
|
+
if channel and not channel.is_closed:
|
|
725
|
+
break
|
|
726
|
+
logger.debug(f"等待通道就绪(第{attempt+1}/{max_wait_attempts}次)")
|
|
727
|
+
await asyncio.sleep(wait_interval)
|
|
728
|
+
channel, _, _ = await self._get_connection_resources()
|
|
729
|
+
if not channel or channel.is_closed:
|
|
730
|
+
raise Exception("通道初始化失败,无法启动消费")
|
|
731
|
+
|
|
708
732
|
# 获取消费状态和资源
|
|
709
|
-
|
|
710
|
-
|
|
733
|
+
_, handler, consumer_tag = await self._get_consume_state()
|
|
734
|
+
_, exchange, queue = await self._get_connection_resources()
|
|
711
735
|
|
|
712
|
-
#
|
|
713
|
-
if
|
|
736
|
+
# 检查是否已在消费(通过 consumer_tag 是否存在判断)
|
|
737
|
+
if consumer_tag:
|
|
714
738
|
logger.info(f"已经在消费中,返回现有consumer_tag: {consumer_tag}")
|
|
715
739
|
return consumer_tag
|
|
716
740
|
|
|
@@ -732,31 +756,31 @@ class RabbitMQClient:
|
|
|
732
756
|
if not new_consumer_tag:
|
|
733
757
|
raise Exception("未能获取到有效的consumer_tag")
|
|
734
758
|
|
|
735
|
-
#
|
|
736
|
-
await self.
|
|
759
|
+
# 更新消费状态(设置消费者标签)
|
|
760
|
+
await self._set_consumer_tag(new_consumer_tag)
|
|
737
761
|
logger.info(
|
|
738
762
|
f"消费者已启动,队列: {queue.name}, tag: {new_consumer_tag}")
|
|
739
763
|
return new_consumer_tag
|
|
740
764
|
except Exception as e:
|
|
741
765
|
# 异常时回滚状态
|
|
742
|
-
await self.
|
|
766
|
+
await self._set_consumer_tag(None)
|
|
743
767
|
logger.error(f"启动消费失败: {str(e)}", exc_info=True)
|
|
744
768
|
raise
|
|
745
769
|
|
|
746
770
|
async def stop_consuming(self) -> None:
|
|
747
771
|
"""停止消费(无锁嵌套,通过原子方法获取/更新状态)"""
|
|
748
772
|
# 获取消费状态和资源
|
|
749
|
-
|
|
773
|
+
_, _, consumer_tag = await self._get_consume_state()
|
|
750
774
|
_, _, queue = await self._get_connection_resources()
|
|
751
775
|
|
|
752
|
-
if not
|
|
776
|
+
if not consumer_tag: # 无消费标签说明未在消费
|
|
753
777
|
logger.info("未处于消费状态,无需停止")
|
|
754
778
|
return
|
|
755
779
|
|
|
756
780
|
logger.info(f"开始停止消费(consumer_tag: {consumer_tag})")
|
|
757
781
|
|
|
758
|
-
#
|
|
759
|
-
await self.
|
|
782
|
+
# 先清除消费标签
|
|
783
|
+
await self._set_consumer_tag(None)
|
|
760
784
|
|
|
761
785
|
# 取消消费者
|
|
762
786
|
if consumer_tag and queue and not await self._is_closed():
|
|
@@ -781,10 +805,6 @@ class RabbitMQClient:
|
|
|
781
805
|
break
|
|
782
806
|
await asyncio.sleep(1)
|
|
783
807
|
|
|
784
|
-
# 清理消费状态
|
|
785
|
-
async with self._consume_state_lock:
|
|
786
|
-
self._consumer_tag = None
|
|
787
|
-
|
|
788
808
|
logger.info(f"已停止消费队列: {queue.name if queue else '未知'}")
|
|
789
809
|
|
|
790
810
|
async def _parse_message(self, message: AbstractIncomingMessage) -> Union[Dict[str, Any], str]:
|
|
@@ -911,21 +931,21 @@ class RabbitMQClient:
|
|
|
911
931
|
|
|
912
932
|
# 重试检查消费状态(处理极端并发场景)
|
|
913
933
|
for attempt in range(max_check_attempts):
|
|
914
|
-
|
|
915
|
-
if
|
|
934
|
+
_, handler, consumer_tag = await self._get_consume_state()
|
|
935
|
+
if consumer_tag and handler: # 有消费标签且有处理器才继续
|
|
916
936
|
break
|
|
917
937
|
if attempt < max_check_attempts - 1:
|
|
918
938
|
logger.debug(
|
|
919
939
|
f"消息 {message_id} 处理状态检查重试(第{attempt+1}次): "
|
|
920
940
|
f"handler={'存在' if handler else '不存在'}, "
|
|
921
|
-
f"
|
|
941
|
+
f"consumer_tag={'存在' if consumer_tag else '不存在'}"
|
|
922
942
|
)
|
|
923
943
|
await asyncio.sleep(check_interval)
|
|
924
944
|
|
|
925
945
|
# 最终状态判断:状态异常则拒绝消息
|
|
926
|
-
|
|
927
|
-
if not
|
|
928
|
-
err_msg = f"消息 {message_id} 拒绝处理:handler={'存在' if handler else '不存在'},
|
|
946
|
+
_, handler, consumer_tag = await self._get_consume_state()
|
|
947
|
+
if not consumer_tag or not handler:
|
|
948
|
+
err_msg = f"消息 {message_id} 拒绝处理:handler={'存在' if handler else '不存在'}, consumer_tag={'存在' if consumer_tag else '不存在'}"
|
|
929
949
|
logger.warning(err_msg)
|
|
930
950
|
try:
|
|
931
951
|
await self._handle_business_retry(message, Exception(err_msg), drop=False)
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/rabbitmq/rabbitmq_service.py
RENAMED
|
@@ -191,6 +191,13 @@ class RabbitMQService:
|
|
|
191
191
|
|
|
192
192
|
# 使用declare_queue控制是否声明队列(发送器不声明,监听器声明)
|
|
193
193
|
await client.connect(declare_queue=not is_sender)
|
|
194
|
+
|
|
195
|
+
# 监听器客户端连接后延迟1秒,确保消费状态就绪(仅首次启动)
|
|
196
|
+
if not is_sender and create_if_not_exists:
|
|
197
|
+
logger.info(
|
|
198
|
+
f"监听器客户端 '{processed_queue_name}' 连接成功,延迟1秒启动消费(解决启动时序问题)")
|
|
199
|
+
await asyncio.sleep(1)
|
|
200
|
+
|
|
194
201
|
return client
|
|
195
202
|
|
|
196
203
|
@classmethod
|
|
@@ -508,6 +515,11 @@ class RabbitMQService:
|
|
|
508
515
|
logger.info("服务关闭中,取消启动消费者")
|
|
509
516
|
return
|
|
510
517
|
|
|
518
|
+
# 监听器启动消费前额外延迟1秒,确保consumer_tag完全生成(不删消息)
|
|
519
|
+
if cls._has_listeners and not client_name.startswith("sender-"):
|
|
520
|
+
logger.info(f"消费者 '{client_name}' 准备启动,延迟1秒等待消费状态就绪(不删除积压消息)")
|
|
521
|
+
await asyncio.sleep(1)
|
|
522
|
+
|
|
511
523
|
# 创建停止事件
|
|
512
524
|
stop_event = asyncio.Event()
|
|
513
525
|
cls._consumer_events[client_name] = stop_event
|
|
@@ -522,6 +534,16 @@ class RabbitMQService:
|
|
|
522
534
|
|
|
523
535
|
while attempt < max_attempts and not stop_event.is_set() and not cls._is_shutdown:
|
|
524
536
|
try:
|
|
537
|
+
# 启动消费前再次校验连接和队列状态
|
|
538
|
+
if not await client.is_connected:
|
|
539
|
+
logger.info(f"消费者 '{client_name}' 连接断开,尝试重连")
|
|
540
|
+
await client.connect(force_reconnect=True, declare_queue=True)
|
|
541
|
+
|
|
542
|
+
# 确保队列已就绪
|
|
543
|
+
_, _, queue = await client._get_connection_resources()
|
|
544
|
+
if not queue:
|
|
545
|
+
raise Exception("队列未初始化完成")
|
|
546
|
+
|
|
525
547
|
consumer_tag = await client.start_consuming()
|
|
526
548
|
if consumer_tag:
|
|
527
549
|
break
|
|
@@ -541,7 +563,8 @@ class RabbitMQService:
|
|
|
541
563
|
|
|
542
564
|
# 记录消费者标签
|
|
543
565
|
cls._consumer_tags[client_name] = consumer_tag
|
|
544
|
-
logger.info(
|
|
566
|
+
logger.info(
|
|
567
|
+
f"消费者 '{client_name}' 开始消费,tag: {consumer_tag}(将处理队列中所有积压消息)")
|
|
545
568
|
|
|
546
569
|
# 等待停止事件
|
|
547
570
|
await stop_event.wait()
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/nacos_service.py
RENAMED
|
@@ -47,7 +47,7 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
47
47
|
self.retry_backoff = self.nacos_config.get('retryBackoff', 1.5)
|
|
48
48
|
self.max_retry_delay = self.nacos_config.get('maxRetryDelay', 30)
|
|
49
49
|
self.heartbeat_interval = self.nacos_config.get(
|
|
50
|
-
'heartbeatInterval',
|
|
50
|
+
'heartbeatInterval', 15)
|
|
51
51
|
self.register_retry_interval = self.nacos_config.get(
|
|
52
52
|
'registerRetryInterval', 5) # 注册重试间隔
|
|
53
53
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/DatabaseConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/EmbeddingConfig.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/config/RerankerConfig.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/database/base_db_service.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/database/database_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/health/health_check.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/logging/logger_wrapper.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/logging/sql_logger.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/context.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/exception.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/middleware.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/monitor_memory.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/timeout.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/middleware/traceid.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/mqlistener_config.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/mqmsg_model.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/models/mqsend_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/rabbitmq/rabbitmq_pool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.1.36 → sycommon_python_lib-0.1.38}/src/sycommon/synacos/feign_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|