jettask 0.2.23__py3-none-any.whl → 0.2.24__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.
- jettask/__init__.py +2 -0
- jettask/cli.py +12 -8
- jettask/config/lua_scripts.py +37 -0
- jettask/config/nacos_config.py +1 -1
- jettask/core/app.py +313 -340
- jettask/core/container.py +4 -4
- jettask/{persistence → core}/namespace.py +93 -27
- jettask/core/task.py +16 -9
- jettask/core/unified_manager_base.py +136 -26
- jettask/db/__init__.py +67 -0
- jettask/db/base.py +137 -0
- jettask/{utils/db_connector.py → db/connector.py} +130 -26
- jettask/db/models/__init__.py +16 -0
- jettask/db/models/scheduled_task.py +196 -0
- jettask/db/models/task.py +77 -0
- jettask/db/models/task_run.py +85 -0
- jettask/executor/__init__.py +0 -15
- jettask/executor/core.py +76 -31
- jettask/executor/process_entry.py +29 -114
- jettask/executor/task_executor.py +4 -0
- jettask/messaging/event_pool.py +928 -685
- jettask/messaging/scanner.py +30 -0
- jettask/persistence/__init__.py +28 -103
- jettask/persistence/buffer.py +170 -0
- jettask/persistence/consumer.py +330 -249
- jettask/persistence/manager.py +304 -0
- jettask/persistence/persistence.py +391 -0
- jettask/scheduler/__init__.py +15 -3
- jettask/scheduler/{task_crud.py → database.py} +61 -57
- jettask/scheduler/loader.py +2 -2
- jettask/scheduler/{scheduler_coordinator.py → manager.py} +23 -6
- jettask/scheduler/models.py +14 -10
- jettask/scheduler/schedule.py +166 -0
- jettask/scheduler/scheduler.py +12 -11
- jettask/schemas/__init__.py +50 -1
- jettask/schemas/backlog.py +43 -6
- jettask/schemas/namespace.py +70 -19
- jettask/schemas/queue.py +19 -3
- jettask/schemas/responses.py +493 -0
- jettask/task/__init__.py +0 -2
- jettask/task/router.py +3 -0
- jettask/test_connection_monitor.py +1 -1
- jettask/utils/__init__.py +7 -5
- jettask/utils/db_init.py +8 -4
- jettask/utils/namespace_dep.py +167 -0
- jettask/utils/queue_matcher.py +186 -0
- jettask/utils/rate_limit/concurrency_limiter.py +7 -1
- jettask/utils/stream_backlog.py +1 -1
- jettask/webui/__init__.py +0 -1
- jettask/webui/api/__init__.py +4 -4
- jettask/webui/api/alerts.py +806 -71
- jettask/webui/api/example_refactored.py +400 -0
- jettask/webui/api/namespaces.py +390 -45
- jettask/webui/api/overview.py +300 -54
- jettask/webui/api/queues.py +971 -267
- jettask/webui/api/scheduled.py +1249 -56
- jettask/webui/api/settings.py +129 -7
- jettask/webui/api/workers.py +442 -0
- jettask/webui/app.py +46 -2329
- jettask/webui/middleware/__init__.py +6 -0
- jettask/webui/middleware/namespace_middleware.py +135 -0
- jettask/webui/services/__init__.py +146 -0
- jettask/webui/services/heartbeat_service.py +251 -0
- jettask/webui/services/overview_service.py +60 -51
- jettask/webui/services/queue_monitor_service.py +426 -0
- jettask/webui/services/redis_monitor_service.py +87 -0
- jettask/webui/services/settings_service.py +174 -111
- jettask/webui/services/task_monitor_service.py +222 -0
- jettask/webui/services/timeline_pg_service.py +452 -0
- jettask/webui/services/timeline_service.py +189 -0
- jettask/webui/services/worker_monitor_service.py +467 -0
- jettask/webui/utils/__init__.py +11 -0
- jettask/webui/utils/time_utils.py +122 -0
- jettask/worker/lifecycle.py +8 -2
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/METADATA +1 -1
- jettask-0.2.24.dist-info/RECORD +142 -0
- jettask/executor/executor.py +0 -338
- jettask/persistence/backlog_monitor.py +0 -567
- jettask/persistence/base.py +0 -2334
- jettask/persistence/db_manager.py +0 -516
- jettask/persistence/maintenance.py +0 -81
- jettask/persistence/message_consumer.py +0 -259
- jettask/persistence/models.py +0 -49
- jettask/persistence/offline_recovery.py +0 -196
- jettask/persistence/queue_discovery.py +0 -215
- jettask/persistence/task_persistence.py +0 -218
- jettask/persistence/task_updater.py +0 -583
- jettask/scheduler/add_execution_count.sql +0 -11
- jettask/scheduler/add_priority_field.sql +0 -26
- jettask/scheduler/add_scheduler_id.sql +0 -25
- jettask/scheduler/add_scheduler_id_index.sql +0 -10
- jettask/scheduler/make_scheduler_id_required.sql +0 -28
- jettask/scheduler/migrate_interval_seconds.sql +0 -9
- jettask/scheduler/performance_optimization.sql +0 -45
- jettask/scheduler/run_scheduler.py +0 -186
- jettask/scheduler/schema.sql +0 -84
- jettask/task/task_executor.py +0 -318
- jettask/webui/api/analytics.py +0 -323
- jettask/webui/config.py +0 -90
- jettask/webui/models/__init__.py +0 -3
- jettask/webui/models/namespace.py +0 -63
- jettask/webui/namespace_manager/__init__.py +0 -10
- jettask/webui/namespace_manager/multi.py +0 -593
- jettask/webui/namespace_manager/unified.py +0 -193
- jettask/webui/run.py +0 -46
- jettask-0.2.23.dist-info/RECORD +0 -145
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/WHEEL +0 -0
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/entry_points.txt +0 -0
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/licenses/LICENSE +0 -0
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
"""
|
2
|
+
Redis 监控基础服务
|
3
|
+
|
4
|
+
提供 Redis 连接管理和基础功能
|
5
|
+
"""
|
6
|
+
import asyncio
|
7
|
+
import logging
|
8
|
+
from typing import Optional
|
9
|
+
import redis.asyncio as aioredis
|
10
|
+
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
class RedisMonitorService:
|
15
|
+
"""Redis 监控基础服务类"""
|
16
|
+
|
17
|
+
def __init__(self, redis_url: str = "redis://localhost:6379", redis_prefix: str = "jettask"):
|
18
|
+
"""
|
19
|
+
初始化 Redis 监控服务
|
20
|
+
|
21
|
+
Args:
|
22
|
+
redis_url: Redis 连接URL
|
23
|
+
redis_prefix: Redis 键前缀
|
24
|
+
"""
|
25
|
+
self.redis_url = redis_url
|
26
|
+
self.redis_prefix = redis_prefix
|
27
|
+
self.redis: Optional[aioredis.Redis] = None
|
28
|
+
self.worker_state_manager = None # 延迟初始化
|
29
|
+
|
30
|
+
# 缓存配置
|
31
|
+
self._queues_cache = None
|
32
|
+
self._queues_cache_time = 0
|
33
|
+
self._queues_cache_ttl = 60 # 缓存60秒
|
34
|
+
|
35
|
+
self._workers_cache = None
|
36
|
+
self._workers_cache_time = 0
|
37
|
+
self._workers_cache_ttl = 5 # worker缓存5秒,因为更新频繁
|
38
|
+
|
39
|
+
async def connect(self):
|
40
|
+
"""连接到 Redis"""
|
41
|
+
from jettask.db.connector import get_async_redis_pool
|
42
|
+
|
43
|
+
pool = get_async_redis_pool(
|
44
|
+
self.redis_url,
|
45
|
+
decode_responses=True,
|
46
|
+
max_connections=100,
|
47
|
+
socket_connect_timeout=5,
|
48
|
+
socket_timeout=10,
|
49
|
+
socket_keepalive=True,
|
50
|
+
health_check_interval=30
|
51
|
+
)
|
52
|
+
self.redis = aioredis.Redis(connection_pool=pool)
|
53
|
+
|
54
|
+
# 初始化 WorkerStateManager
|
55
|
+
from jettask.worker.lifecycle import WorkerStateManager
|
56
|
+
self.worker_state_manager = WorkerStateManager(
|
57
|
+
redis_client=self.redis,
|
58
|
+
redis_prefix=self.redis_prefix
|
59
|
+
)
|
60
|
+
logger.info(f"Redis 监控服务已连接: {self.redis_url}")
|
61
|
+
|
62
|
+
async def close(self):
|
63
|
+
"""关闭 Redis 连接"""
|
64
|
+
if self.redis:
|
65
|
+
await self.redis.close()
|
66
|
+
logger.info("Redis 监控服务已关闭")
|
67
|
+
|
68
|
+
def get_prefixed_queue_name(self, queue_name: str) -> str:
|
69
|
+
"""
|
70
|
+
为队列名称添加前缀
|
71
|
+
|
72
|
+
Args:
|
73
|
+
queue_name: 原始队列名称
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
带前缀的队列名称
|
77
|
+
"""
|
78
|
+
return f"{self.redis_prefix}:QUEUE:{queue_name}"
|
79
|
+
|
80
|
+
async def __aenter__(self):
|
81
|
+
"""异步上下文管理器入口"""
|
82
|
+
await self.connect()
|
83
|
+
return self
|
84
|
+
|
85
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
86
|
+
"""异步上下文管理器退出"""
|
87
|
+
await self.close()
|
@@ -9,7 +9,8 @@ from datetime import datetime
|
|
9
9
|
from sqlalchemy import text
|
10
10
|
from urllib.parse import urlparse
|
11
11
|
|
12
|
-
from jettask.
|
12
|
+
from jettask.db.connector import get_async_redis_client, get_pg_engine_and_factory
|
13
|
+
from jettask.config.task_center import task_center_config
|
13
14
|
from jettask.schemas import (
|
14
15
|
ConfigMode,
|
15
16
|
NamespaceCreate,
|
@@ -111,8 +112,9 @@ class SettingsService:
|
|
111
112
|
Returns:
|
112
113
|
命名空间列表
|
113
114
|
"""
|
114
|
-
|
115
|
-
|
115
|
+
# 获取元数据库会话
|
116
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
117
|
+
async with session_factory() as session:
|
116
118
|
query = """
|
117
119
|
SELECT id, name, description, redis_config, pg_config,
|
118
120
|
is_active, version, created_at, updated_at
|
@@ -137,36 +139,45 @@ class SettingsService:
|
|
137
139
|
# 构建响应
|
138
140
|
redis_config_dict = row.redis_config if row.redis_config else {}
|
139
141
|
pg_config_dict = row.pg_config if row.pg_config else {}
|
140
|
-
|
141
|
-
#
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
142
|
+
|
143
|
+
# 获取配置模式
|
144
|
+
redis_config_mode = redis_config_dict.get('config_mode', 'direct')
|
145
|
+
pg_config_mode = pg_config_dict.get('config_mode', 'direct')
|
146
|
+
|
147
|
+
# Redis 配置处理 - 根据模式返回不同内容
|
148
|
+
if redis_config_mode == 'nacos':
|
149
|
+
# Nacos 模式 - 只返回 nacos_key,不返回真实 URL(保密)
|
150
|
+
redis_url = None
|
151
|
+
redis_nacos_key = redis_config_dict.get('nacos_key')
|
152
|
+
logger.debug(f"命名空间 {row.name} 使用 Nacos 模式,返回 Redis key: {redis_nacos_key}")
|
151
153
|
else:
|
154
|
+
# Direct 模式 - 返回真实完整的 URL(客户端需要使用)
|
152
155
|
redis_url = redis_config_dict.get('url', '')
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
156
|
+
redis_nacos_key = None
|
157
|
+
logger.debug(f"命名空间 {row.name} 使用 Direct 模式,返回真实 Redis URL")
|
158
|
+
|
159
|
+
# PostgreSQL 配置处理 - 根据模式返回不同内容
|
160
|
+
if pg_config_mode == 'nacos':
|
161
|
+
# Nacos 模式 - 只返回 nacos_key,不返回真实 URL(保密)
|
162
|
+
pg_url = None
|
163
|
+
pg_nacos_key = pg_config_dict.get('nacos_key')
|
164
|
+
logger.debug(f"命名空间 {row.name} 使用 Nacos 模式,返回 PG key: {pg_nacos_key}")
|
162
165
|
else:
|
166
|
+
# Direct 模式 - 返回真实完整的 URL(客户端需要使用)
|
163
167
|
pg_url = pg_config_dict.get('url')
|
164
|
-
|
168
|
+
pg_nacos_key = None
|
169
|
+
if pg_url:
|
170
|
+
logger.debug(f"命名空间 {row.name} 使用 Direct 模式,返回真实 PG URL")
|
171
|
+
|
165
172
|
response = NamespaceResponse(
|
166
173
|
name=row.name,
|
167
174
|
description=row.description,
|
168
175
|
redis_url=redis_url,
|
176
|
+
redis_config_mode=redis_config_mode,
|
177
|
+
redis_nacos_key=redis_nacos_key,
|
169
178
|
pg_url=pg_url,
|
179
|
+
pg_config_mode=pg_config_mode,
|
180
|
+
pg_nacos_key=pg_nacos_key,
|
170
181
|
connection_url=f"/api/v1/namespaces/{row.name}",
|
171
182
|
version=row.version or 1,
|
172
183
|
enabled=row.is_active,
|
@@ -188,8 +199,9 @@ class SettingsService:
|
|
188
199
|
Returns:
|
189
200
|
创建的命名空间信息
|
190
201
|
"""
|
191
|
-
|
192
|
-
|
202
|
+
# 获取元数据库会话
|
203
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
204
|
+
async with session_factory() as session:
|
193
205
|
# 检查命名空间是否已存在
|
194
206
|
check_query = text("SELECT COUNT(*) FROM namespaces WHERE name = :name")
|
195
207
|
result = await session.execute(check_query, {'name': namespace.name})
|
@@ -264,19 +276,44 @@ class SettingsService:
|
|
264
276
|
|
265
277
|
row = result.fetchone()
|
266
278
|
await session.commit()
|
267
|
-
|
268
|
-
# 构建响应 -
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
279
|
+
|
280
|
+
# 构建响应 - 根据配置模式返回不同内容
|
281
|
+
config_mode_str = namespace.config_mode.value
|
282
|
+
|
283
|
+
if namespace.config_mode == ConfigMode.NACOS:
|
284
|
+
# Nacos 模式 - 只返回 nacos_key,不返回真实 URL(保密)
|
285
|
+
response = NamespaceResponse(
|
286
|
+
name=row.name,
|
287
|
+
description=row.description,
|
288
|
+
redis_url=None,
|
289
|
+
redis_config_mode=config_mode_str,
|
290
|
+
redis_nacos_key=redis_config.get('nacos_key'),
|
291
|
+
pg_url=None,
|
292
|
+
pg_config_mode=config_mode_str,
|
293
|
+
pg_nacos_key=pg_config.get('nacos_key'),
|
294
|
+
connection_url=f"/api/v1/namespaces/{row.name}",
|
295
|
+
version=row.version or 1,
|
296
|
+
enabled=row.is_active,
|
297
|
+
created_at=row.created_at,
|
298
|
+
updated_at=row.updated_at
|
299
|
+
)
|
300
|
+
else:
|
301
|
+
# Direct 模式 - 返回真实完整的 URL(客户端需要使用)
|
302
|
+
response = NamespaceResponse(
|
303
|
+
name=row.name,
|
304
|
+
description=row.description,
|
305
|
+
redis_url=redis_config.get('url'),
|
306
|
+
redis_config_mode=config_mode_str,
|
307
|
+
redis_nacos_key=None,
|
308
|
+
pg_url=pg_config.get('url'),
|
309
|
+
pg_config_mode=config_mode_str,
|
310
|
+
pg_nacos_key=None,
|
311
|
+
connection_url=f"/api/v1/namespaces/{row.name}",
|
312
|
+
version=row.version or 1,
|
313
|
+
enabled=row.is_active,
|
314
|
+
created_at=row.created_at,
|
315
|
+
updated_at=row.updated_at
|
316
|
+
)
|
280
317
|
|
281
318
|
logger.info(f"成功创建命名空间: {namespace.name}")
|
282
319
|
return response
|
@@ -292,10 +329,11 @@ class SettingsService:
|
|
292
329
|
Returns:
|
293
330
|
命名空间信息
|
294
331
|
"""
|
295
|
-
|
296
|
-
|
332
|
+
# 获取元数据库会话
|
333
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
334
|
+
async with session_factory() as session:
|
297
335
|
query = text("""
|
298
|
-
SELECT id, name, description, redis_config, pg_config,
|
336
|
+
SELECT id, name, description, redis_config, pg_config,
|
299
337
|
is_active, version, created_at, updated_at
|
300
338
|
FROM namespaces
|
301
339
|
WHERE name = :name
|
@@ -306,40 +344,49 @@ class SettingsService:
|
|
306
344
|
|
307
345
|
if not row:
|
308
346
|
raise ValueError(f"命名空间 '{namespace_name}' 不存在")
|
309
|
-
|
347
|
+
|
310
348
|
# 构建响应
|
311
349
|
redis_config_dict = row.redis_config if row.redis_config else {}
|
312
350
|
pg_config_dict = row.pg_config if row.pg_config else {}
|
313
|
-
|
314
|
-
#
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
351
|
+
|
352
|
+
# 获取配置模式
|
353
|
+
redis_config_mode = redis_config_dict.get('config_mode', 'direct')
|
354
|
+
pg_config_mode = pg_config_dict.get('config_mode', 'direct')
|
355
|
+
|
356
|
+
# Redis 配置处理 - 根据模式返回不同内容
|
357
|
+
if redis_config_mode == 'nacos':
|
358
|
+
# Nacos 模式 - 只返回 nacos_key,不返回真实 URL(保密)
|
359
|
+
redis_url = None
|
360
|
+
redis_nacos_key = redis_config_dict.get('nacos_key')
|
361
|
+
logger.debug(f"命名空间 {namespace_name} 使用 Nacos 模式,返回 Redis key: {redis_nacos_key}")
|
324
362
|
else:
|
363
|
+
# Direct 模式 - 返回真实完整的 URL(客户端需要使用)
|
325
364
|
redis_url = redis_config_dict.get('url', '')
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
365
|
+
redis_nacos_key = None
|
366
|
+
logger.debug(f"命名空间 {namespace_name} 使用 Direct 模式,返回真实 Redis URL")
|
367
|
+
|
368
|
+
# PostgreSQL 配置处理 - 根据模式返回不同内容
|
369
|
+
if pg_config_mode == 'nacos':
|
370
|
+
# Nacos 模式 - 只返回 nacos_key,不返回真实 URL(保密)
|
371
|
+
pg_url = None
|
372
|
+
pg_nacos_key = pg_config_dict.get('nacos_key')
|
373
|
+
logger.debug(f"命名空间 {namespace_name} 使用 Nacos 模式,返回 PG key: {pg_nacos_key}")
|
335
374
|
else:
|
375
|
+
# Direct 模式 - 返回真实完整的 URL(客户端需要使用)
|
336
376
|
pg_url = pg_config_dict.get('url')
|
337
|
-
|
377
|
+
pg_nacos_key = None
|
378
|
+
if pg_url:
|
379
|
+
logger.debug(f"命名空间 {namespace_name} 使用 Direct 模式,返回真实 PG URL")
|
380
|
+
|
338
381
|
response = NamespaceResponse(
|
339
382
|
name=row.name,
|
340
383
|
description=row.description,
|
341
384
|
redis_url=redis_url,
|
385
|
+
redis_config_mode=redis_config_mode,
|
386
|
+
redis_nacos_key=redis_nacos_key,
|
342
387
|
pg_url=pg_url,
|
388
|
+
pg_config_mode=pg_config_mode,
|
389
|
+
pg_nacos_key=pg_nacos_key,
|
343
390
|
connection_url=f"/api/v1/namespaces/{row.name}",
|
344
391
|
version=row.version or 1,
|
345
392
|
enabled=row.is_active,
|
@@ -361,8 +408,9 @@ class SettingsService:
|
|
361
408
|
Returns:
|
362
409
|
更新后的命名空间信息
|
363
410
|
"""
|
364
|
-
|
365
|
-
|
411
|
+
# 获取元数据库会话
|
412
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
413
|
+
async with session_factory() as session:
|
366
414
|
# 检查命名空间是否存在
|
367
415
|
check_query = text("""
|
368
416
|
SELECT id, redis_config, pg_config FROM namespaces WHERE name = :name
|
@@ -510,40 +558,49 @@ class SettingsService:
|
|
510
558
|
result = await session.execute(update_query, params)
|
511
559
|
updated_row = result.fetchone()
|
512
560
|
await session.commit()
|
513
|
-
|
561
|
+
|
514
562
|
# 构建响应
|
515
|
-
redis_config_dict = updated_row.redis_config
|
563
|
+
redis_config_dict = updated_row.redis_config if updated_row.redis_config else {}
|
516
564
|
pg_config_dict = updated_row.pg_config if updated_row.pg_config else {}
|
517
|
-
|
518
|
-
#
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
565
|
+
|
566
|
+
# 获取配置模式
|
567
|
+
redis_config_mode = redis_config_dict.get('config_mode', 'direct')
|
568
|
+
pg_config_mode = pg_config_dict.get('config_mode', 'direct')
|
569
|
+
|
570
|
+
# Redis 配置处理 - 根据模式返回不同内容
|
571
|
+
if redis_config_mode == 'nacos':
|
572
|
+
# Nacos 模式 - 只返回 nacos_key,不返回真实 URL(保密)
|
573
|
+
redis_url = None
|
574
|
+
redis_nacos_key = redis_config_dict.get('nacos_key')
|
575
|
+
logger.debug(f"更新后命名空间 {namespace_name} 使用 Nacos 模式,返回 Redis key: {redis_nacos_key}")
|
528
576
|
else:
|
577
|
+
# Direct 模式 - 返回真实完整的 URL(客户端需要使用)
|
529
578
|
redis_url = redis_config_dict.get('url', '')
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
579
|
+
redis_nacos_key = None
|
580
|
+
logger.debug(f"更新后命名空间 {namespace_name} 使用 Direct 模式,返回真实 Redis URL")
|
581
|
+
|
582
|
+
# PostgreSQL 配置处理 - 根据模式返回不同内容
|
583
|
+
if pg_config_mode == 'nacos':
|
584
|
+
# Nacos 模式 - 只返回 nacos_key,不返回真实 URL(保密)
|
585
|
+
pg_url = None
|
586
|
+
pg_nacos_key = pg_config_dict.get('nacos_key')
|
587
|
+
logger.debug(f"更新后命名空间 {namespace_name} 使用 Nacos 模式,返回 PG key: {pg_nacos_key}")
|
539
588
|
else:
|
589
|
+
# Direct 模式 - 返回真实完整的 URL(客户端需要使用)
|
540
590
|
pg_url = pg_config_dict.get('url')
|
541
|
-
|
591
|
+
pg_nacos_key = None
|
592
|
+
if pg_url:
|
593
|
+
logger.debug(f"更新后命名空间 {namespace_name} 使用 Direct 模式,返回真实 PG URL")
|
594
|
+
|
542
595
|
response = NamespaceResponse(
|
543
596
|
name=updated_row.name,
|
544
597
|
description=updated_row.description,
|
545
598
|
redis_url=redis_url,
|
599
|
+
redis_config_mode=redis_config_mode,
|
600
|
+
redis_nacos_key=redis_nacos_key,
|
546
601
|
pg_url=pg_url,
|
602
|
+
pg_config_mode=pg_config_mode,
|
603
|
+
pg_nacos_key=pg_nacos_key,
|
547
604
|
connection_url=f"/api/v1/namespaces/{updated_row.name}",
|
548
605
|
version=updated_row.version or 1,
|
549
606
|
enabled=updated_row.is_active,
|
@@ -567,9 +624,10 @@ class SettingsService:
|
|
567
624
|
"""
|
568
625
|
if namespace_name == 'default':
|
569
626
|
raise ValueError("不能删除默认命名空间")
|
570
|
-
|
571
|
-
|
572
|
-
|
627
|
+
|
628
|
+
# 获取元数据库会话
|
629
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
630
|
+
async with session_factory() as session:
|
573
631
|
# 检查命名空间是否存在
|
574
632
|
check_query = text("SELECT id FROM namespaces WHERE name = :name")
|
575
633
|
result = await session.execute(check_query, {'name': namespace_name})
|
@@ -596,11 +654,12 @@ class SettingsService:
|
|
596
654
|
Returns:
|
597
655
|
激活结果
|
598
656
|
"""
|
599
|
-
|
600
|
-
|
657
|
+
# 获取元数据库会话
|
658
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
659
|
+
async with session_factory() as session:
|
601
660
|
# 检查并激活命名空间
|
602
661
|
update_query = text("""
|
603
|
-
UPDATE namespaces
|
662
|
+
UPDATE namespaces
|
604
663
|
SET is_active = true, updated_at = CURRENT_TIMESTAMP
|
605
664
|
WHERE name = :name
|
606
665
|
""")
|
@@ -628,12 +687,13 @@ class SettingsService:
|
|
628
687
|
"""
|
629
688
|
if namespace_name == 'default':
|
630
689
|
raise ValueError("不能停用默认命名空间")
|
631
|
-
|
632
|
-
|
633
|
-
|
690
|
+
|
691
|
+
# 获取元数据库会话
|
692
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
693
|
+
async with session_factory() as session:
|
634
694
|
# 检查并停用命名空间
|
635
695
|
update_query = text("""
|
636
|
-
UPDATE namespaces
|
696
|
+
UPDATE namespaces
|
637
697
|
SET is_active = false, updated_at = CURRENT_TIMESTAMP
|
638
698
|
WHERE name = :name
|
639
699
|
""")
|
@@ -652,18 +712,18 @@ class SettingsService:
|
|
652
712
|
async def get_namespace_statistics(namespace_name: str) -> Dict[str, Any]:
|
653
713
|
"""
|
654
714
|
获取命名空间统计信息
|
655
|
-
|
715
|
+
|
656
716
|
Args:
|
657
717
|
namespace_name: 命名空间名称
|
658
|
-
|
718
|
+
|
659
719
|
Returns:
|
660
|
-
|
720
|
+
统计信息(符合 NamespaceStatisticsResponse 格式)
|
661
721
|
"""
|
662
722
|
# 这里可以根据实际需求实现统计逻辑
|
663
723
|
# 暂时返回模拟数据
|
664
724
|
return {
|
665
|
-
"
|
666
|
-
"
|
725
|
+
"success": True,
|
726
|
+
"data": {
|
667
727
|
"total_queues": 0,
|
668
728
|
"total_tasks": 0,
|
669
729
|
"active_workers": 0,
|
@@ -672,6 +732,7 @@ class SettingsService:
|
|
672
732
|
"completed_tasks": 0,
|
673
733
|
"failed_tasks": 0
|
674
734
|
},
|
735
|
+
"namespace": namespace_name,
|
675
736
|
"timestamp": datetime.now().isoformat()
|
676
737
|
}
|
677
738
|
|
@@ -686,11 +747,12 @@ class SettingsService:
|
|
686
747
|
Returns:
|
687
748
|
激活结果
|
688
749
|
"""
|
689
|
-
|
690
|
-
|
750
|
+
# 获取元数据库会话
|
751
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
752
|
+
async with session_factory() as session:
|
691
753
|
# 批量激活
|
692
754
|
update_query = text("""
|
693
|
-
UPDATE namespaces
|
755
|
+
UPDATE namespaces
|
694
756
|
SET is_active = true, updated_at = CURRENT_TIMESTAMP
|
695
757
|
WHERE name = ANY(:names)
|
696
758
|
""")
|
@@ -726,12 +788,13 @@ class SettingsService:
|
|
726
788
|
"namespaces": [],
|
727
789
|
"skipped": ["default"]
|
728
790
|
}
|
729
|
-
|
730
|
-
|
731
|
-
|
791
|
+
|
792
|
+
# 获取元数据库会话
|
793
|
+
_, session_factory = get_pg_engine_and_factory(task_center_config.meta_database_url)
|
794
|
+
async with session_factory() as session:
|
732
795
|
# 批量停用
|
733
796
|
update_query = text("""
|
734
|
-
UPDATE namespaces
|
797
|
+
UPDATE namespaces
|
735
798
|
SET is_active = false, updated_at = CURRENT_TIMESTAMP
|
736
799
|
WHERE name = ANY(:names)
|
737
800
|
""")
|