sycommon-python-lib 0.2.0b1__py3-none-any.whl → 0.2.0b2__py3-none-any.whl
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/rabbitmq/rabbitmq_service_client_manager.py +48 -24
- {sycommon_python_lib-0.2.0b1.dist-info → sycommon_python_lib-0.2.0b2.dist-info}/METADATA +1 -1
- {sycommon_python_lib-0.2.0b1.dist-info → sycommon_python_lib-0.2.0b2.dist-info}/RECORD +6 -6
- {sycommon_python_lib-0.2.0b1.dist-info → sycommon_python_lib-0.2.0b2.dist-info}/WHEEL +0 -0
- {sycommon_python_lib-0.2.0b1.dist-info → sycommon_python_lib-0.2.0b2.dist-info}/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.0b1.dist-info → sycommon_python_lib-0.2.0b2.dist-info}/top_level.txt +0 -0
|
@@ -28,62 +28,86 @@ class RabbitMQClientManager(RabbitMQCoreService):
|
|
|
28
28
|
|
|
29
29
|
@classmethod
|
|
30
30
|
async def _clean_client_resources(cls, client: RabbitMQClient) -> None:
|
|
31
|
-
"""
|
|
31
|
+
"""
|
|
32
|
+
清理客户端无效资源(修正版:只清理消费行为,不关闭 Channel)
|
|
33
|
+
|
|
34
|
+
重要变更:
|
|
35
|
+
- 移除了 await client._channel.close() 调用。
|
|
36
|
+
- 原因:关闭 Channel 可能会触发底层连接的 close_callback,导致重连死锁或冲突。
|
|
37
|
+
- Channel 的关闭应该由 RabbitMQClient.connect() 内部的重建逻辑接管。
|
|
38
|
+
"""
|
|
32
39
|
try:
|
|
33
|
-
# 1.
|
|
40
|
+
# 1. 尝试正常停止消费(发送 basic_cancel)
|
|
34
41
|
if client._consumer_tag:
|
|
35
42
|
await client.stop_consuming()
|
|
36
43
|
except Exception as e:
|
|
37
44
|
logger.warning(f"停止消费逻辑异常: {str(e)}")
|
|
38
45
|
|
|
46
|
+
# 注意:这里不再显式关闭 client._channel
|
|
47
|
+
# 原因:
|
|
48
|
+
# 1. 如果是消费者独立通道,关闭它是安全的,但不如交给 connect() 统一处理(重建前关闭)。
|
|
49
|
+
# 2. 如果是生产者主通道(由 Pool 缓存),绝对不能在这里关闭!否则会影响其他生产者。
|
|
50
|
+
# 3. connect() 方法已经包含了 "显式关闭旧 Channel" 的逻辑,这里重复操作是多余的且危险的。
|
|
51
|
+
|
|
39
52
|
try:
|
|
40
|
-
# 2.
|
|
41
|
-
#
|
|
42
|
-
# 生产者持有的主通道虽然通常由 Pool 管理,但这里为了彻底清理,
|
|
43
|
-
# 可以尝试关闭(Pool 内部会有保护,或者接受主通道被关闭后重新创建)。
|
|
44
|
-
if client._channel and not client._channel.is_closed:
|
|
45
|
-
try:
|
|
46
|
-
await client._channel.close()
|
|
47
|
-
logger.debug(f"清理资源:已关闭客户端通道")
|
|
48
|
-
except Exception as e:
|
|
49
|
-
logger.warning(f"清理资源:关闭通道异常: {e}")
|
|
50
|
-
except Exception as e:
|
|
51
|
-
logger.warning(f"清理资源过程发生异常: {str(e)}")
|
|
52
|
-
finally:
|
|
53
|
-
# 3. 强制重置客户端状态
|
|
54
|
-
# 注意:不要将 _channel_conn 置空,因为它是连接池的引用,置空后可能导致逻辑判断出错
|
|
55
|
-
# 但为了彻底断开,置空也是安全的,因为 connect 会重新获取。
|
|
53
|
+
# 2. 重置客户端状态引用(为后续 connect() 扫清障碍)
|
|
54
|
+
# 注意:虽然清理了状态,但不要清空 _message_handler!
|
|
56
55
|
client._channel = None
|
|
57
56
|
client._channel_conn = None
|
|
58
57
|
client._exchange = None
|
|
59
58
|
client._queue = None
|
|
60
59
|
client._consumer_tag = None
|
|
60
|
+
except Exception as e:
|
|
61
|
+
logger.warning(f"重置客户端状态异常: {str(e)}")
|
|
61
62
|
|
|
62
63
|
@classmethod
|
|
63
64
|
async def _reconnect_client(cls, client_name: str, client: RabbitMQClient) -> bool:
|
|
64
|
-
"""
|
|
65
|
+
"""客户端重连(修正版:保存与恢复 Handler,确保消费可恢复)"""
|
|
65
66
|
if cls._is_shutdown or not (cls._connection_pool and await cls._connection_pool.is_alive):
|
|
66
67
|
return False
|
|
67
68
|
|
|
68
69
|
# 重连冷却
|
|
69
70
|
await asyncio.sleep(cls.RECONNECT_INTERVAL)
|
|
70
71
|
|
|
72
|
+
# 【关键修复 1】状态快照
|
|
73
|
+
# 在清理资源前,保存关键状态,因为 _clean_client_resources 不会清空它,
|
|
74
|
+
# 但为了防御性编程,以及后续逻辑的清晰,我们显式保存。
|
|
75
|
+
saved_handler = client._message_handler
|
|
76
|
+
saved_queue_name = client.queue_name
|
|
77
|
+
|
|
71
78
|
try:
|
|
72
|
-
# 清理旧资源
|
|
79
|
+
# 1. 清理旧资源
|
|
80
|
+
# 修正后的版本:只停止消费,不关闭 Channel
|
|
73
81
|
await cls._clean_client_resources(client)
|
|
74
82
|
|
|
75
|
-
#
|
|
83
|
+
# 2. 【关键修复 2】立即恢复 MessageHandler
|
|
84
|
+
# connect() 方法依赖 self._message_handler 来判断是否执行 "was_consuming" 的恢复逻辑。
|
|
85
|
+
# 如果不恢复,connect() 虽然会连上,但会跳过 start_consuming。
|
|
86
|
+
if saved_handler:
|
|
87
|
+
client._message_handler = saved_handler
|
|
88
|
+
|
|
89
|
+
# 防御性恢复队列名
|
|
90
|
+
if saved_queue_name:
|
|
91
|
+
client.queue_name = saved_queue_name
|
|
92
|
+
|
|
93
|
+
# 3. 执行重连
|
|
94
|
+
# 此时 client 处于“空资源但有 Handler”的状态,正是 connect() 期望的状态
|
|
76
95
|
await client.connect()
|
|
77
96
|
|
|
78
97
|
# 验证重连结果
|
|
79
98
|
if await client.is_connected:
|
|
80
|
-
logger.info(f"客户端 '{client_name}' 重连成功")
|
|
99
|
+
logger.info(f"✅ 客户端 '{client_name}' 重连成功")
|
|
81
100
|
return True
|
|
82
101
|
else:
|
|
83
|
-
logger.warning(f"客户端 '{client_name}' 重连失败:资源未完全初始化")
|
|
102
|
+
logger.warning(f"⚠️ 客户端 '{client_name}' 重连失败:资源未完全初始化")
|
|
84
103
|
return False
|
|
104
|
+
|
|
85
105
|
except Exception as e:
|
|
86
|
-
logger.error(
|
|
106
|
+
logger.error(
|
|
107
|
+
f"❌ 客户端 '{client_name}' 重连失败: {str(e)}", exc_info=True)
|
|
108
|
+
# 异常情况下也尝试恢复 handler,以便下次重试能成功
|
|
109
|
+
if saved_handler:
|
|
110
|
+
client._message_handler = saved_handler
|
|
87
111
|
return False
|
|
88
112
|
|
|
89
113
|
@classmethod
|
|
@@ -54,7 +54,7 @@ sycommon/notice/uvicorn_monitor.py,sha256=PrC-OFRE71mL8TcbfdkJRKbjwGAbgsWtyBPWIw
|
|
|
54
54
|
sycommon/rabbitmq/rabbitmq_client.py,sha256=MC4QNSZpfYSPHY8-iW3RRuZAs0MZcNGWJD9EzCLc68k,22115
|
|
55
55
|
sycommon/rabbitmq/rabbitmq_pool.py,sha256=igQ4Yh96oZyM8UEhNa_rljhZcitHwske3UsjPtBuj8c,18946
|
|
56
56
|
sycommon/rabbitmq/rabbitmq_service.py,sha256=XSHo9HuIJ_lq-vizRh4xJVdZr_2zLqeLhot09qb0euA,2025
|
|
57
|
-
sycommon/rabbitmq/rabbitmq_service_client_manager.py,sha256=
|
|
57
|
+
sycommon/rabbitmq/rabbitmq_service_client_manager.py,sha256=NrJI4JKyItrMwQUFVZu0GWAx8krUdgUeyessFuUWhjo,10280
|
|
58
58
|
sycommon/rabbitmq/rabbitmq_service_connection_monitor.py,sha256=uvoMuJDzJ9i63uVRq1NKFV10CvkbGnTMyEoq2rgjQx8,3013
|
|
59
59
|
sycommon/rabbitmq/rabbitmq_service_consumer_manager.py,sha256=489r1RKd5WrTNMAcWCxUZpt9yWGrNunZlLCCp-M_rzM,11497
|
|
60
60
|
sycommon/rabbitmq/rabbitmq_service_core.py,sha256=6RMvIf78DmEOZmN8dA0duA9oy4ieNswdGrOeyJdD6tU,4753
|
|
@@ -84,8 +84,8 @@ sycommon/tools/merge_headers.py,sha256=u9u8_1ZIuGIminWsw45YJ5qnsx9MB-Fot0VPge7it
|
|
|
84
84
|
sycommon/tools/snowflake.py,sha256=xQlYXwYnI85kSJ1rZ89gMVBhzemP03xrMPVX9vVa3MY,9228
|
|
85
85
|
sycommon/tools/syemail.py,sha256=BDFhgf7WDOQeTcjxJEQdu0dQhnHFPO_p3eI0-Ni3LhQ,5612
|
|
86
86
|
sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
|
|
87
|
-
sycommon_python_lib-0.2.
|
|
88
|
-
sycommon_python_lib-0.2.
|
|
89
|
-
sycommon_python_lib-0.2.
|
|
90
|
-
sycommon_python_lib-0.2.
|
|
91
|
-
sycommon_python_lib-0.2.
|
|
87
|
+
sycommon_python_lib-0.2.0b2.dist-info/METADATA,sha256=YydQcYEWv2QGklHoJKu2z1mn8UT-Xtr8V_m0xW0Ig00,7372
|
|
88
|
+
sycommon_python_lib-0.2.0b2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
89
|
+
sycommon_python_lib-0.2.0b2.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
|
|
90
|
+
sycommon_python_lib-0.2.0b2.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
|
|
91
|
+
sycommon_python_lib-0.2.0b2.dist-info/RECORD,,
|
|
File without changes
|
{sycommon_python_lib-0.2.0b1.dist-info → sycommon_python_lib-0.2.0b2.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b1.dist-info → sycommon_python_lib-0.2.0b2.dist-info}/top_level.txt
RENAMED
|
File without changes
|