sycommon-python-lib 0.1.34__py3-none-any.whl → 0.1.35__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.
Potentially problematic release.
This version of sycommon-python-lib might be problematic. Click here for more details.
- sycommon/rabbitmq/rabbitmq_client.py +530 -271
- sycommon/rabbitmq/rabbitmq_service.py +213 -115
- sycommon/services.py +58 -26
- sycommon/synacos/feign.py +22 -9
- {sycommon_python_lib-0.1.34.dist-info → sycommon_python_lib-0.1.35.dist-info}/METADATA +1 -1
- {sycommon_python_lib-0.1.34.dist-info → sycommon_python_lib-0.1.35.dist-info}/RECORD +9 -9
- {sycommon_python_lib-0.1.34.dist-info → sycommon_python_lib-0.1.35.dist-info}/WHEEL +0 -0
- {sycommon_python_lib-0.1.34.dist-info → sycommon_python_lib-0.1.35.dist-info}/entry_points.txt +0 -0
- {sycommon_python_lib-0.1.34.dist-info → sycommon_python_lib-0.1.35.dist-info}/top_level.txt +0 -0
sycommon/services.py
CHANGED
|
@@ -22,6 +22,7 @@ class Services(metaclass=SingletonMeta):
|
|
|
22
22
|
_instance: Optional['Services'] = None
|
|
23
23
|
_app: Optional[FastAPI] = None
|
|
24
24
|
_user_lifespan: Optional[Callable] = None
|
|
25
|
+
_shutdown_lock: asyncio.Lock = asyncio.Lock()
|
|
25
26
|
|
|
26
27
|
def __init__(self, config: dict, app: FastAPI):
|
|
27
28
|
if not Services._config:
|
|
@@ -66,8 +67,12 @@ class Services(metaclass=SingletonMeta):
|
|
|
66
67
|
if not cls._config:
|
|
67
68
|
config = yaml.safe_load(open('app.yaml', 'r', encoding='utf-8'))
|
|
68
69
|
cls._config = config
|
|
69
|
-
|
|
70
|
-
app.
|
|
70
|
+
# 使用config
|
|
71
|
+
app.state.config = {
|
|
72
|
+
"host": cls._config.get('Host', '0.0.0.0'),
|
|
73
|
+
"port": cls._config.get('Port', 8080),
|
|
74
|
+
"workers": cls._config.get('Workers', 1)
|
|
75
|
+
}
|
|
71
76
|
|
|
72
77
|
# 立即配置非异步服务(在应用启动前)
|
|
73
78
|
if middleware:
|
|
@@ -139,10 +144,18 @@ class Services(metaclass=SingletonMeta):
|
|
|
139
144
|
has_listeners: bool = False,
|
|
140
145
|
has_senders: bool = False,
|
|
141
146
|
):
|
|
142
|
-
"""异步设置MQ
|
|
147
|
+
"""异步设置MQ相关服务(适配新的RabbitMQService)"""
|
|
143
148
|
# 初始化RabbitMQ服务,传递状态
|
|
144
149
|
RabbitMQService.init(self._config, has_listeners, has_senders)
|
|
145
150
|
|
|
151
|
+
# 等待RabbitMQ连接池初始化完成(最多等待30秒)
|
|
152
|
+
start_time = asyncio.get_event_loop().time()
|
|
153
|
+
while not RabbitMQService._connection_pool and not RabbitMQService._is_shutdown:
|
|
154
|
+
if asyncio.get_event_loop().time() - start_time > 30:
|
|
155
|
+
raise TimeoutError("RabbitMQ连接池初始化超时")
|
|
156
|
+
logging.info("等待RabbitMQ连接池初始化...")
|
|
157
|
+
await asyncio.sleep(1)
|
|
158
|
+
|
|
146
159
|
# 设置发送器,传递是否有监听器的标志
|
|
147
160
|
if rabbitmq_senders:
|
|
148
161
|
# 判断是否有监听器,如果有遍历监听器列表,队列名一样将prefetch_count属性设置到发送器对象中
|
|
@@ -159,20 +172,25 @@ class Services(metaclass=SingletonMeta):
|
|
|
159
172
|
|
|
160
173
|
# 验证初始化结果
|
|
161
174
|
if has_listeners:
|
|
175
|
+
# 异步获取客户端数量(适配新的RabbitMQService)
|
|
162
176
|
listener_count = len(RabbitMQService._clients)
|
|
163
177
|
logging.info(f"监听器初始化完成,共启动 {listener_count} 个消费者")
|
|
164
178
|
if listener_count == 0:
|
|
165
179
|
logging.warning("未成功初始化任何监听器,请检查配置")
|
|
166
180
|
|
|
167
181
|
async def _setup_senders_async(self, rabbitmq_senders, has_listeners: bool):
|
|
182
|
+
"""设置发送器(适配新的RabbitMQService异步方法)"""
|
|
168
183
|
Services._registered_senders = [
|
|
169
184
|
sender.queue_name for sender in rabbitmq_senders]
|
|
170
185
|
|
|
171
|
-
# 将是否有监听器的信息传递给RabbitMQService
|
|
186
|
+
# 将是否有监听器的信息传递给RabbitMQService(异步调用)
|
|
172
187
|
await RabbitMQService.setup_senders(rabbitmq_senders, has_listeners)
|
|
188
|
+
# 更新已注册的发送器(从RabbitMQService获取实际注册的名称)
|
|
189
|
+
Services._registered_senders = RabbitMQService._sender_client_names
|
|
173
190
|
logging.info(f"已注册的RabbitMQ发送器: {Services._registered_senders}")
|
|
174
191
|
|
|
175
192
|
async def _setup_listeners_async(self, rabbitmq_listeners, has_senders: bool):
|
|
193
|
+
"""设置监听器(适配新的RabbitMQService异步方法)"""
|
|
176
194
|
await RabbitMQService.setup_listeners(rabbitmq_listeners, has_senders)
|
|
177
195
|
|
|
178
196
|
@classmethod
|
|
@@ -183,27 +201,30 @@ class Services(metaclass=SingletonMeta):
|
|
|
183
201
|
max_retries: int = 3,
|
|
184
202
|
retry_delay: float = 1.0, **kwargs
|
|
185
203
|
) -> None:
|
|
186
|
-
"""
|
|
204
|
+
"""发送消息,添加重试机制(适配新的RabbitMQService异步API)"""
|
|
187
205
|
if not cls._initialized or not cls._loop:
|
|
188
206
|
logging.error("Services not properly initialized!")
|
|
189
207
|
raise ValueError("服务未正确初始化")
|
|
190
208
|
|
|
209
|
+
if RabbitMQService._is_shutdown:
|
|
210
|
+
logging.error("RabbitMQService已关闭,无法发送消息")
|
|
211
|
+
raise RuntimeError("RabbitMQ服务已关闭")
|
|
212
|
+
|
|
191
213
|
for attempt in range(max_retries):
|
|
192
214
|
try:
|
|
215
|
+
# 验证发送器是否注册
|
|
193
216
|
if queue_name not in cls._registered_senders:
|
|
194
217
|
cls._registered_senders = RabbitMQService._sender_client_names
|
|
195
218
|
if queue_name not in cls._registered_senders:
|
|
196
219
|
raise ValueError(f"发送器 {queue_name} 未注册")
|
|
197
220
|
|
|
198
|
-
|
|
221
|
+
# 获取发送器(适配新的异步get_sender方法)
|
|
222
|
+
sender = await RabbitMQService.get_sender(queue_name)
|
|
199
223
|
if not sender:
|
|
200
|
-
raise ValueError(f"发送器 '{queue_name}'
|
|
224
|
+
raise ValueError(f"发送器 '{queue_name}' 不存在或连接无效")
|
|
201
225
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
await sender.connect(force_reconnect=True, declare_queue=False)
|
|
205
|
-
|
|
206
|
-
await RabbitMQService.send_message(data, queue_name, ** kwargs)
|
|
226
|
+
# 发送消息(调用RabbitMQService的异步send_message)
|
|
227
|
+
await RabbitMQService.send_message(data, queue_name, **kwargs)
|
|
207
228
|
logging.info(f"消息发送成功(尝试 {attempt+1}/{max_retries})")
|
|
208
229
|
return
|
|
209
230
|
|
|
@@ -219,17 +240,28 @@ class Services(metaclass=SingletonMeta):
|
|
|
219
240
|
)
|
|
220
241
|
await asyncio.sleep(retry_delay)
|
|
221
242
|
|
|
222
|
-
@
|
|
223
|
-
async def shutdown():
|
|
224
|
-
"""
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
243
|
+
@classmethod
|
|
244
|
+
async def shutdown(cls):
|
|
245
|
+
"""关闭所有服务(线程安全,适配新的RabbitMQService关闭逻辑)"""
|
|
246
|
+
async with cls._shutdown_lock:
|
|
247
|
+
if RabbitMQService._is_shutdown:
|
|
248
|
+
logging.info("RabbitMQService已关闭,无需重复操作")
|
|
249
|
+
return
|
|
250
|
+
|
|
251
|
+
# 取消所有MQ任务
|
|
252
|
+
for task in Services._mq_tasks:
|
|
253
|
+
if not task.done():
|
|
254
|
+
task.cancel()
|
|
255
|
+
try:
|
|
256
|
+
await task
|
|
257
|
+
except asyncio.CancelledError:
|
|
258
|
+
logging.info(f"MQ任务 {task.get_name()} 已取消")
|
|
259
|
+
|
|
260
|
+
# 关闭RabbitMQ服务(异步调用)
|
|
261
|
+
await RabbitMQService.shutdown()
|
|
262
|
+
|
|
263
|
+
# 清理全局状态
|
|
264
|
+
cls._initialized = False
|
|
265
|
+
cls._registered_senders.clear()
|
|
266
|
+
cls._mq_tasks.clear()
|
|
267
|
+
logging.info("所有服务已关闭")
|
sycommon/synacos/feign.py
CHANGED
|
@@ -123,15 +123,28 @@ async def feign(service_name, api_path, method='GET', params=None, headers=None,
|
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
async def _handle_feign_response(response):
|
|
126
|
-
"""处理Feign
|
|
127
|
-
|
|
128
|
-
content_type = response.headers.get('Content-Type')
|
|
126
|
+
"""处理Feign请求的响应,统一返回格式"""
|
|
127
|
+
try:
|
|
128
|
+
content_type = response.headers.get('Content-Type', '')
|
|
129
129
|
if 'application/json' in content_type:
|
|
130
|
-
|
|
130
|
+
response_body = await response.json()
|
|
131
131
|
else:
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
response_body = await response.text()
|
|
133
|
+
except Exception as e:
|
|
134
|
+
response_body = f"读取响应体失败: {str(e)}"
|
|
135
|
+
SYLogger.error(f"nacos:处理响应时出错: {response_body}")
|
|
136
|
+
|
|
137
|
+
if response.status == 200:
|
|
138
|
+
if 'application/octet-stream' in content_type:
|
|
139
|
+
return io.BytesIO(await response.read()) # 重新读取二进制内容
|
|
140
|
+
return response_body
|
|
134
141
|
else:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
142
|
+
# 失败:返回统一错误字典,包含状态码、响应体
|
|
143
|
+
error_msg = f"请求失败,状态码: {response.status},响应内容: {response_body}"
|
|
144
|
+
SYLogger.error(error_msg)
|
|
145
|
+
return {
|
|
146
|
+
"success": False,
|
|
147
|
+
"code": response.status,
|
|
148
|
+
"message": error_msg,
|
|
149
|
+
"data": response_body
|
|
150
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
command/cli.py,sha256=bP2LCLkRvfETIwWkVD70q5xFxMI4D3BpH09Ws1f-ENc,5849
|
|
2
2
|
sycommon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
sycommon/services.py,sha256=
|
|
3
|
+
sycommon/services.py,sha256=e9odPBLUoAAUkFU4s8ITIQUbr1GH7dqb9qSHyUhN4A8,11258
|
|
4
4
|
sycommon/config/Config.py,sha256=9yO5b8WfvEDvkyrGrlwrLFasgh_-MjcEvGF20Gz5Xo4,3041
|
|
5
5
|
sycommon/config/DatabaseConfig.py,sha256=ILiUuYT9_xJZE2W-RYuC3JCt_YLKc1sbH13-MHIOPhg,804
|
|
6
6
|
sycommon/config/EmbeddingConfig.py,sha256=gPKwiDYbeu1GpdIZXMmgqM7JqBIzCXi0yYuGRLZooMI,362
|
|
@@ -35,16 +35,16 @@ sycommon/models/mqlistener_config.py,sha256=vXp2uMmd0XQ5B9noSRXWHewTy-juQ2y7IsWt
|
|
|
35
35
|
sycommon/models/mqmsg_model.py,sha256=cxn0M5b0utQK6crMYmL-1waeGYHvK3AlGaRy23clqTE,277
|
|
36
36
|
sycommon/models/mqsend_config.py,sha256=NQX9dc8PpuquMG36GCVhJe8omAW1KVXXqr6lSRU6D7I,268
|
|
37
37
|
sycommon/models/sso_user.py,sha256=i1WAN6k5sPcPApQEdtjpWDy7VrzWLpOrOQewGLGoGIw,2702
|
|
38
|
-
sycommon/rabbitmq/rabbitmq_client.py,sha256=
|
|
38
|
+
sycommon/rabbitmq/rabbitmq_client.py,sha256=Zb3A1SFY7JTL0TtvZU2WwMoRDx3IDI28u7L1L9z8Rn4,41304
|
|
39
39
|
sycommon/rabbitmq/rabbitmq_pool.py,sha256=_NMOO4CZy-I_anMqpzfYinz-8373_rg5FM9eqzdjGyU,3598
|
|
40
|
-
sycommon/rabbitmq/rabbitmq_service.py,sha256=
|
|
40
|
+
sycommon/rabbitmq/rabbitmq_service.py,sha256=XW_TFWXCgmR8jKB7nZllpijFdj-9O5h80KWSOxhaMJA,35282
|
|
41
41
|
sycommon/sse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
42
|
sycommon/sse/event.py,sha256=k_rBJy23R7crtzQeetT0Q73D8o5-5p-eESGSs_BPOj0,2797
|
|
43
43
|
sycommon/sse/sse.py,sha256=__CfWEcYxOxQ-HpLor4LTZ5hLWqw9-2X7CngqbVHsfw,10128
|
|
44
44
|
sycommon/synacos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
45
|
sycommon/synacos/example.py,sha256=61XL03tU8WTNOo3FUduf93F2fAwah1S0lbH1ufhRhRk,5739
|
|
46
46
|
sycommon/synacos/example2.py,sha256=adUaru3Hy482KrOA17DfaC4nwvLj8etIDS_KrWLWmCU,4811
|
|
47
|
-
sycommon/synacos/feign.py,sha256=
|
|
47
|
+
sycommon/synacos/feign.py,sha256=gD5r_H2ZhqdxjRIvYTt6l5DoKyGihyTzkQgrMVqbzlw,6057
|
|
48
48
|
sycommon/synacos/feign_client.py,sha256=JxzxohrsscQNlAjRVo_3ZQrMQSfVHFOtRYyEnP6sDGk,15205
|
|
49
49
|
sycommon/synacos/nacos_service.py,sha256=SO1s83Y8A5jyQNFhk7ZZ_BrGQyGZ8TXBKtzRYxI-uDQ,34661
|
|
50
50
|
sycommon/synacos/param.py,sha256=KcfSkxnXOa0TGmCjY8hdzU9pzUsA8-4PeyBKWI2-568,1765
|
|
@@ -52,8 +52,8 @@ sycommon/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
52
52
|
sycommon/tools/docs.py,sha256=OPj2ETheuWjXLyaXtaZPbwmJKfJaYXV5s4XMVAUNrms,1607
|
|
53
53
|
sycommon/tools/snowflake.py,sha256=DdEj3T5r5OEvikp3puxqmmmz6BrggxomoSlnsRFb5dM,1174
|
|
54
54
|
sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
|
|
55
|
-
sycommon_python_lib-0.1.
|
|
56
|
-
sycommon_python_lib-0.1.
|
|
57
|
-
sycommon_python_lib-0.1.
|
|
58
|
-
sycommon_python_lib-0.1.
|
|
59
|
-
sycommon_python_lib-0.1.
|
|
55
|
+
sycommon_python_lib-0.1.35.dist-info/METADATA,sha256=j34xKIYcABwKu196AEWCX6nMbRzDwpRSSpLdWPWGZ74,7037
|
|
56
|
+
sycommon_python_lib-0.1.35.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
57
|
+
sycommon_python_lib-0.1.35.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
|
|
58
|
+
sycommon_python_lib-0.1.35.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
|
|
59
|
+
sycommon_python_lib-0.1.35.dist-info/RECORD,,
|
|
File without changes
|
{sycommon_python_lib-0.1.34.dist-info → sycommon_python_lib-0.1.35.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|