jettask 0.2.18__py3-none-any.whl → 0.2.20__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 +60 -2
- jettask/cli.py +314 -228
- jettask/config/__init__.py +9 -1
- jettask/config/config.py +245 -0
- jettask/config/env_loader.py +381 -0
- jettask/config/lua_scripts.py +158 -0
- jettask/config/nacos_config.py +132 -5
- jettask/core/__init__.py +1 -1
- jettask/core/app.py +1573 -666
- jettask/core/app_importer.py +33 -16
- jettask/core/container.py +532 -0
- jettask/core/task.py +1 -4
- jettask/core/unified_manager_base.py +2 -2
- jettask/executor/__init__.py +38 -0
- jettask/executor/core.py +625 -0
- jettask/executor/executor.py +338 -0
- jettask/executor/orchestrator.py +290 -0
- jettask/executor/process_entry.py +638 -0
- jettask/executor/task_executor.py +317 -0
- jettask/messaging/__init__.py +68 -0
- jettask/messaging/event_pool.py +2188 -0
- jettask/messaging/reader.py +519 -0
- jettask/messaging/registry.py +266 -0
- jettask/messaging/scanner.py +369 -0
- jettask/messaging/sender.py +312 -0
- jettask/persistence/__init__.py +118 -0
- jettask/persistence/backlog_monitor.py +567 -0
- jettask/{backend/data_access.py → persistence/base.py} +58 -57
- jettask/persistence/consumer.py +315 -0
- jettask/{core → persistence}/db_manager.py +23 -22
- jettask/persistence/maintenance.py +81 -0
- jettask/persistence/message_consumer.py +259 -0
- jettask/{backend/namespace_data_access.py → persistence/namespace.py} +66 -98
- jettask/persistence/offline_recovery.py +196 -0
- jettask/persistence/queue_discovery.py +215 -0
- jettask/persistence/task_persistence.py +218 -0
- jettask/persistence/task_updater.py +583 -0
- jettask/scheduler/__init__.py +2 -2
- jettask/scheduler/loader.py +6 -5
- jettask/scheduler/run_scheduler.py +1 -1
- jettask/scheduler/scheduler.py +7 -7
- jettask/scheduler/{unified_scheduler_manager.py → scheduler_coordinator.py} +18 -13
- jettask/task/__init__.py +16 -0
- jettask/{router.py → task/router.py} +26 -8
- jettask/task/task_center/__init__.py +9 -0
- jettask/task/task_executor.py +318 -0
- jettask/task/task_registry.py +291 -0
- jettask/test_connection_monitor.py +73 -0
- jettask/utils/__init__.py +31 -1
- jettask/{monitor/run_backlog_collector.py → utils/backlog_collector.py} +1 -1
- jettask/utils/db_connector.py +1629 -0
- jettask/{db_init.py → utils/db_init.py} +1 -1
- jettask/utils/rate_limit/__init__.py +30 -0
- jettask/utils/rate_limit/concurrency_limiter.py +665 -0
- jettask/utils/rate_limit/config.py +145 -0
- jettask/utils/rate_limit/limiter.py +41 -0
- jettask/utils/rate_limit/manager.py +269 -0
- jettask/utils/rate_limit/qps_limiter.py +154 -0
- jettask/utils/rate_limit/task_limiter.py +384 -0
- jettask/utils/serializer.py +3 -0
- jettask/{monitor/stream_backlog_monitor.py → utils/stream_backlog.py} +14 -6
- jettask/utils/time_sync.py +173 -0
- jettask/webui/__init__.py +27 -0
- jettask/{api/v1 → webui/api}/alerts.py +1 -1
- jettask/{api/v1 → webui/api}/analytics.py +2 -2
- jettask/{api/v1 → webui/api}/namespaces.py +1 -1
- jettask/{api/v1 → webui/api}/overview.py +1 -1
- jettask/{api/v1 → webui/api}/queues.py +3 -3
- jettask/{api/v1 → webui/api}/scheduled.py +1 -1
- jettask/{api/v1 → webui/api}/settings.py +1 -1
- jettask/{api.py → webui/app.py} +253 -145
- jettask/webui/namespace_manager/__init__.py +10 -0
- jettask/{multi_namespace_consumer.py → webui/namespace_manager/multi.py} +69 -22
- jettask/{unified_consumer_manager.py → webui/namespace_manager/unified.py} +1 -1
- jettask/{run.py → webui/run.py} +2 -2
- jettask/{services → webui/services}/__init__.py +1 -3
- jettask/{services → webui/services}/overview_service.py +34 -16
- jettask/{services → webui/services}/queue_service.py +1 -1
- jettask/{backend → webui/services}/queue_stats_v2.py +1 -1
- jettask/{services → webui/services}/settings_service.py +1 -1
- jettask/worker/__init__.py +53 -0
- jettask/worker/lifecycle.py +1507 -0
- jettask/worker/manager.py +583 -0
- jettask/{core/offline_worker_recovery.py → worker/recovery.py} +268 -175
- {jettask-0.2.18.dist-info → jettask-0.2.20.dist-info}/METADATA +2 -71
- jettask-0.2.20.dist-info/RECORD +145 -0
- jettask/__main__.py +0 -140
- jettask/api/__init__.py +0 -103
- jettask/backend/__init__.py +0 -1
- jettask/backend/api/__init__.py +0 -3
- jettask/backend/api/v1/__init__.py +0 -17
- jettask/backend/api/v1/monitoring.py +0 -431
- jettask/backend/api/v1/namespaces.py +0 -504
- jettask/backend/api/v1/queues.py +0 -342
- jettask/backend/api/v1/tasks.py +0 -367
- jettask/backend/core/__init__.py +0 -3
- jettask/backend/core/cache.py +0 -221
- jettask/backend/core/database.py +0 -200
- jettask/backend/core/exceptions.py +0 -102
- jettask/backend/dependencies.py +0 -261
- jettask/backend/init_meta_db.py +0 -158
- jettask/backend/main.py +0 -1426
- jettask/backend/main_unified.py +0 -78
- jettask/backend/main_v2.py +0 -394
- jettask/backend/models/__init__.py +0 -3
- jettask/backend/models/requests.py +0 -236
- jettask/backend/models/responses.py +0 -230
- jettask/backend/namespace_api_old.py +0 -267
- jettask/backend/services/__init__.py +0 -3
- jettask/backend/start.py +0 -42
- jettask/backend/unified_api_router.py +0 -1541
- jettask/cleanup_deprecated_tables.sql +0 -16
- jettask/core/consumer_manager.py +0 -1695
- jettask/core/delay_scanner.py +0 -256
- jettask/core/event_pool.py +0 -1700
- jettask/core/heartbeat_process.py +0 -222
- jettask/core/task_batch.py +0 -153
- jettask/core/worker_scanner.py +0 -271
- jettask/executors/__init__.py +0 -5
- jettask/executors/asyncio.py +0 -876
- jettask/executors/base.py +0 -30
- jettask/executors/common.py +0 -148
- jettask/executors/multi_asyncio.py +0 -309
- jettask/gradio_app.py +0 -570
- jettask/integrated_gradio_app.py +0 -1088
- jettask/main.py +0 -0
- jettask/monitoring/__init__.py +0 -3
- jettask/pg_consumer.py +0 -1896
- jettask/run_monitor.py +0 -22
- jettask/run_webui.py +0 -148
- jettask/scheduler/multi_namespace_scheduler.py +0 -294
- jettask/scheduler/unified_manager.py +0 -450
- jettask/task_center_client.py +0 -150
- jettask/utils/serializer_optimized.py +0 -33
- jettask/webui_exceptions.py +0 -67
- jettask-0.2.18.dist-info/RECORD +0 -150
- /jettask/{constants.py → config/constants.py} +0 -0
- /jettask/{backend/config.py → config/task_center.py} +0 -0
- /jettask/{pg_consumer → messaging/pg_consumer}/pg_consumer_v2.py +0 -0
- /jettask/{pg_consumer → messaging/pg_consumer}/sql/add_execution_time_field.sql +0 -0
- /jettask/{pg_consumer → messaging/pg_consumer}/sql/create_new_tables.sql +0 -0
- /jettask/{pg_consumer → messaging/pg_consumer}/sql/create_tables_v3.sql +0 -0
- /jettask/{pg_consumer → messaging/pg_consumer}/sql/migrate_to_new_structure.sql +0 -0
- /jettask/{pg_consumer → messaging/pg_consumer}/sql/modify_time_fields.sql +0 -0
- /jettask/{pg_consumer → messaging/pg_consumer}/sql_utils.py +0 -0
- /jettask/{models.py → persistence/models.py} +0 -0
- /jettask/scheduler/{manager.py → task_crud.py} +0 -0
- /jettask/{schema.sql → schemas/schema.sql} +0 -0
- /jettask/{task_center.py → task/task_center/client.py} +0 -0
- /jettask/{monitoring → utils}/file_watcher.py +0 -0
- /jettask/{services/redis_monitor_service.py → utils/redis_monitor.py} +0 -0
- /jettask/{api/v1 → webui/api}/__init__.py +0 -0
- /jettask/{webui_config.py → webui/config.py} +0 -0
- /jettask/{webui_models → webui/models}/__init__.py +0 -0
- /jettask/{webui_models → webui/models}/namespace.py +0 -0
- /jettask/{services → webui/services}/alert_service.py +0 -0
- /jettask/{services → webui/services}/analytics_service.py +0 -0
- /jettask/{services → webui/services}/scheduled_task_service.py +0 -0
- /jettask/{services → webui/services}/task_service.py +0 -0
- /jettask/{webui_sql → webui/sql}/batch_upsert_functions.sql +0 -0
- /jettask/{webui_sql → webui/sql}/verify_database.sql +0 -0
- {jettask-0.2.18.dist-info → jettask-0.2.20.dist-info}/WHEEL +0 -0
- {jettask-0.2.18.dist-info → jettask-0.2.20.dist-info}/entry_points.txt +0 -0
- {jettask-0.2.18.dist-info → jettask-0.2.20.dist-info}/licenses/LICENSE +0 -0
- {jettask-0.2.18.dist-info → jettask-0.2.20.dist-info}/top_level.txt +0 -0
jettask/backend/main_unified.py
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
统一的FastAPI应用主文件
|
3
|
-
简化版本,所有API接口都在unified_api_router.py中定义
|
4
|
-
"""
|
5
|
-
|
6
|
-
from fastapi import FastAPI
|
7
|
-
from fastapi.middleware.cors import CORSMiddleware
|
8
|
-
from fastapi.staticfiles import StaticFiles
|
9
|
-
import logging
|
10
|
-
import os
|
11
|
-
|
12
|
-
# 导入统一的路由器
|
13
|
-
try:
|
14
|
-
from unified_api_router import router as api_router
|
15
|
-
except ImportError:
|
16
|
-
# 如果相对导入失败,尝试绝对导入
|
17
|
-
from jettask.backend.unified_api_router import router as api_router
|
18
|
-
|
19
|
-
# 设置日志
|
20
|
-
logging.basicConfig(
|
21
|
-
level=logging.INFO,
|
22
|
-
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
23
|
-
)
|
24
|
-
logger = logging.getLogger(__name__)
|
25
|
-
|
26
|
-
# 创建FastAPI应用
|
27
|
-
app = FastAPI(
|
28
|
-
title="JetTask WebUI API",
|
29
|
-
description="统一的任务队列管理系统API",
|
30
|
-
version="2.0.0"
|
31
|
-
)
|
32
|
-
|
33
|
-
# 配置CORS
|
34
|
-
app.add_middleware(
|
35
|
-
CORSMiddleware,
|
36
|
-
allow_origins=["*"], # 在生产环境中应该设置具体的域名
|
37
|
-
allow_credentials=True,
|
38
|
-
allow_methods=["*"],
|
39
|
-
allow_headers=["*"],
|
40
|
-
)
|
41
|
-
|
42
|
-
# 注册统一的API路由
|
43
|
-
app.include_router(api_router)
|
44
|
-
|
45
|
-
# 静态文件服务(如果需要)
|
46
|
-
frontend_path = os.path.join(os.path.dirname(__file__), "../frontend/dist")
|
47
|
-
if os.path.exists(frontend_path):
|
48
|
-
app.mount("/", StaticFiles(directory=frontend_path, html=True), name="static")
|
49
|
-
logger.info(f"Serving static files from {frontend_path}")
|
50
|
-
|
51
|
-
# 健康检查端点
|
52
|
-
@app.get("/health")
|
53
|
-
async def health_check():
|
54
|
-
"""健康检查端点"""
|
55
|
-
return {"status": "healthy", "service": "jettask-webui"}
|
56
|
-
|
57
|
-
# 启动事件
|
58
|
-
@app.on_event("startup")
|
59
|
-
async def startup_event():
|
60
|
-
"""应用启动事件"""
|
61
|
-
logger.info("JetTask WebUI API 启动成功")
|
62
|
-
logger.info("所有API接口已统一到 unified_api_router.py 文件中")
|
63
|
-
|
64
|
-
# 关闭事件
|
65
|
-
@app.on_event("shutdown")
|
66
|
-
async def shutdown_event():
|
67
|
-
"""应用关闭事件"""
|
68
|
-
logger.info("JetTask WebUI API 正在关闭...")
|
69
|
-
|
70
|
-
if __name__ == "__main__":
|
71
|
-
import uvicorn
|
72
|
-
uvicorn.run(
|
73
|
-
"main_unified:app",
|
74
|
-
host="0.0.0.0",
|
75
|
-
port=8001,
|
76
|
-
reload=True,
|
77
|
-
log_level="info"
|
78
|
-
)
|
jettask/backend/main_v2.py
DELETED
@@ -1,394 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
JetTask WebUI Backend v2 - Refactored and Optimized
|
3
|
-
|
4
|
-
重构后的主要改进:
|
5
|
-
1. 模块化架构,职责分离清晰
|
6
|
-
2. 统一的错误处理和响应格式
|
7
|
-
3. 缓存系统优化性能
|
8
|
-
4. 依赖注入提升可测试性
|
9
|
-
5. 监控和日志系统完善
|
10
|
-
"""
|
11
|
-
import sys
|
12
|
-
import os
|
13
|
-
import asyncio
|
14
|
-
import time
|
15
|
-
from contextlib import asynccontextmanager
|
16
|
-
from datetime import datetime, timezone
|
17
|
-
import logging
|
18
|
-
|
19
|
-
from fastapi import FastAPI, Request, HTTPException
|
20
|
-
from fastapi.middleware.cors import CORSMiddleware
|
21
|
-
from fastapi.middleware.gzip import GZipMiddleware
|
22
|
-
from fastapi.responses import JSONResponse
|
23
|
-
from fastapi.exceptions import RequestValidationError
|
24
|
-
|
25
|
-
# 添加项目路径
|
26
|
-
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
27
|
-
|
28
|
-
# 导入核心模块
|
29
|
-
from core.database import db_manager
|
30
|
-
from core.cache import cache_manager
|
31
|
-
from core.exceptions import JetTaskAPIException
|
32
|
-
|
33
|
-
# 导入API路由
|
34
|
-
from api.v1 import v1_router
|
35
|
-
|
36
|
-
# 导入原有路由(向后兼容)
|
37
|
-
from namespace_api import router as namespace_router_old
|
38
|
-
from queue_backlog_api import router as backlog_router_old
|
39
|
-
|
40
|
-
# 设置日志
|
41
|
-
logging.basicConfig(
|
42
|
-
level=logging.INFO,
|
43
|
-
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
44
|
-
)
|
45
|
-
logger = logging.getLogger(__name__)
|
46
|
-
|
47
|
-
# 应用启动时间
|
48
|
-
APP_START_TIME = time.time()
|
49
|
-
|
50
|
-
|
51
|
-
@asynccontextmanager
|
52
|
-
async def lifespan(app: FastAPI):
|
53
|
-
"""应用生命周期管理"""
|
54
|
-
# 启动时初始化
|
55
|
-
startup_start = time.time()
|
56
|
-
|
57
|
-
try:
|
58
|
-
logger.info("=" * 60)
|
59
|
-
logger.info("JetTask WebUI Backend v2 启动中...")
|
60
|
-
|
61
|
-
# 1. 初始化缓存管理器
|
62
|
-
if os.getenv('REDIS_URL'):
|
63
|
-
from core.database import get_redis_client
|
64
|
-
redis_client = await get_redis_client(os.getenv('REDIS_URL'), "cache")
|
65
|
-
cache_manager.redis_client = redis_client
|
66
|
-
logger.info("缓存管理器已初始化 (Redis)")
|
67
|
-
else:
|
68
|
-
logger.info("缓存管理器已初始化 (本地缓存)")
|
69
|
-
|
70
|
-
# 2. 初始化数据库连接池
|
71
|
-
pg_url = os.getenv('JETTASK_PG_URL', 'postgresql://jettask:123456@localhost:5432/jettask')
|
72
|
-
await db_manager.get_pg_pool(pg_url, "default")
|
73
|
-
logger.info(f"数据库连接池已初始化: {pg_url.split('@')[1] if '@' in pg_url else pg_url}")
|
74
|
-
|
75
|
-
# 3. 初始化命名空间数据访问
|
76
|
-
from namespace_data_access import get_namespace_data_access
|
77
|
-
namespace_data_access = get_namespace_data_access()
|
78
|
-
logger.info("命名空间数据访问已初始化")
|
79
|
-
|
80
|
-
startup_duration = time.time() - startup_start
|
81
|
-
logger.info(f"系统启动完成,耗时: {startup_duration:.2f}s")
|
82
|
-
logger.info("=" * 60)
|
83
|
-
|
84
|
-
except Exception as e:
|
85
|
-
logger.error(f"启动失败: {e}")
|
86
|
-
raise
|
87
|
-
|
88
|
-
yield
|
89
|
-
|
90
|
-
# 关闭时清理资源
|
91
|
-
try:
|
92
|
-
logger.info("正在关闭系统...")
|
93
|
-
|
94
|
-
# 清理数据库连接
|
95
|
-
await db_manager.close_all()
|
96
|
-
|
97
|
-
# 清理缓存
|
98
|
-
cache_stats = cache_manager.get_stats()
|
99
|
-
logger.info(f"缓存统计: {cache_stats}")
|
100
|
-
|
101
|
-
logger.info("系统关闭完成")
|
102
|
-
|
103
|
-
except Exception as e:
|
104
|
-
logger.error(f"关闭时出错: {e}")
|
105
|
-
|
106
|
-
|
107
|
-
# 创建FastAPI应用
|
108
|
-
app = FastAPI(
|
109
|
-
title="JetTask WebUI Backend",
|
110
|
-
version="2.0.0",
|
111
|
-
description="重构优化的JetTask监控后端API",
|
112
|
-
lifespan=lifespan,
|
113
|
-
docs_url="/docs",
|
114
|
-
redoc_url="/redoc",
|
115
|
-
openapi_url="/openapi.json"
|
116
|
-
)
|
117
|
-
|
118
|
-
# 添加中间件
|
119
|
-
app.add_middleware(GZipMiddleware, minimum_size=1000)
|
120
|
-
app.add_middleware(
|
121
|
-
CORSMiddleware,
|
122
|
-
allow_origins=["*"], # 生产环境应配置具体域名
|
123
|
-
allow_credentials=True,
|
124
|
-
allow_methods=["*"],
|
125
|
-
allow_headers=["*"],
|
126
|
-
)
|
127
|
-
|
128
|
-
|
129
|
-
# 请求计时中间件
|
130
|
-
@app.middleware("http")
|
131
|
-
async def log_requests(request: Request, call_next):
|
132
|
-
start_time = time.time()
|
133
|
-
|
134
|
-
# 记录请求开始
|
135
|
-
logger.debug(f"开始处理请求: {request.method} {request.url}")
|
136
|
-
|
137
|
-
response = await call_next(request)
|
138
|
-
|
139
|
-
# 记录请求完成
|
140
|
-
duration = time.time() - start_time
|
141
|
-
logger.info(
|
142
|
-
f"{request.method} {request.url.path} - "
|
143
|
-
f"状态码: {response.status_code} - "
|
144
|
-
f"耗时: {duration:.3f}s"
|
145
|
-
)
|
146
|
-
|
147
|
-
# 添加响应头
|
148
|
-
response.headers["X-Response-Time"] = f"{duration:.3f}s"
|
149
|
-
response.headers["X-API-Version"] = "2.0.0"
|
150
|
-
|
151
|
-
return response
|
152
|
-
|
153
|
-
|
154
|
-
# 全局异常处理器
|
155
|
-
@app.exception_handler(JetTaskAPIException)
|
156
|
-
async def jettask_exception_handler(request: Request, exc: JetTaskAPIException):
|
157
|
-
"""处理自定义API异常"""
|
158
|
-
return JSONResponse(
|
159
|
-
status_code=exc.status_code,
|
160
|
-
content={
|
161
|
-
"success": False,
|
162
|
-
"error_code": exc.error_code,
|
163
|
-
"message": exc.detail,
|
164
|
-
"details": exc.extra_data,
|
165
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
166
|
-
"path": str(request.url)
|
167
|
-
}
|
168
|
-
)
|
169
|
-
|
170
|
-
|
171
|
-
@app.exception_handler(RequestValidationError)
|
172
|
-
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
173
|
-
"""处理请求验证异常"""
|
174
|
-
return JSONResponse(
|
175
|
-
status_code=422,
|
176
|
-
content={
|
177
|
-
"success": False,
|
178
|
-
"error_code": "VALIDATION_ERROR",
|
179
|
-
"message": "请求参数验证失败",
|
180
|
-
"details": {
|
181
|
-
"errors": exc.errors(),
|
182
|
-
"body": exc.body
|
183
|
-
},
|
184
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
185
|
-
"path": str(request.url)
|
186
|
-
}
|
187
|
-
)
|
188
|
-
|
189
|
-
|
190
|
-
@app.exception_handler(HTTPException)
|
191
|
-
async def http_exception_handler(request: Request, exc: HTTPException):
|
192
|
-
"""处理HTTP异常"""
|
193
|
-
return JSONResponse(
|
194
|
-
status_code=exc.status_code,
|
195
|
-
content={
|
196
|
-
"success": False,
|
197
|
-
"error_code": f"HTTP_{exc.status_code}",
|
198
|
-
"message": exc.detail,
|
199
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
200
|
-
"path": str(request.url)
|
201
|
-
}
|
202
|
-
)
|
203
|
-
|
204
|
-
|
205
|
-
@app.exception_handler(Exception)
|
206
|
-
async def general_exception_handler(request: Request, exc: Exception):
|
207
|
-
"""处理未知异常"""
|
208
|
-
logger.exception(f"未处理的异常: {exc}")
|
209
|
-
return JSONResponse(
|
210
|
-
status_code=500,
|
211
|
-
content={
|
212
|
-
"success": False,
|
213
|
-
"error_code": "INTERNAL_SERVER_ERROR",
|
214
|
-
"message": "内部服务器错误",
|
215
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
216
|
-
"path": str(request.url)
|
217
|
-
}
|
218
|
-
)
|
219
|
-
|
220
|
-
|
221
|
-
# 根路由
|
222
|
-
@app.get("/")
|
223
|
-
async def root():
|
224
|
-
"""API根路径"""
|
225
|
-
uptime = time.time() - APP_START_TIME
|
226
|
-
|
227
|
-
return {
|
228
|
-
"name": "JetTask WebUI Backend",
|
229
|
-
"version": "2.0.0",
|
230
|
-
"status": "healthy",
|
231
|
-
"uptime_seconds": round(uptime, 2),
|
232
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
233
|
-
"features": [
|
234
|
-
"模块化架构",
|
235
|
-
"统一错误处理",
|
236
|
-
"智能缓存",
|
237
|
-
"性能监控",
|
238
|
-
"向后兼容"
|
239
|
-
],
|
240
|
-
"endpoints": {
|
241
|
-
"v1_api": "/api/v1",
|
242
|
-
"v2_docs": "/docs",
|
243
|
-
"health": "/health",
|
244
|
-
"metrics": "/metrics"
|
245
|
-
}
|
246
|
-
}
|
247
|
-
|
248
|
-
|
249
|
-
@app.get("/health")
|
250
|
-
async def health_check():
|
251
|
-
"""健康检查"""
|
252
|
-
uptime = time.time() - APP_START_TIME
|
253
|
-
|
254
|
-
# 检查各组件状态
|
255
|
-
components = {"api": "healthy"}
|
256
|
-
|
257
|
-
# 检查数据库连接
|
258
|
-
try:
|
259
|
-
if "default" in db_manager._pg_pools:
|
260
|
-
components["postgresql"] = "healthy"
|
261
|
-
else:
|
262
|
-
components["postgresql"] = "not_configured"
|
263
|
-
except Exception as e:
|
264
|
-
components["postgresql"] = f"unhealthy: {str(e)}"
|
265
|
-
|
266
|
-
# 检查缓存
|
267
|
-
try:
|
268
|
-
cache_stats = cache_manager.get_stats()
|
269
|
-
components["cache"] = f"healthy (hit_rate: {cache_stats['hit_rate']:.2%})"
|
270
|
-
except Exception as e:
|
271
|
-
components["cache"] = f"unhealthy: {str(e)}"
|
272
|
-
|
273
|
-
# 确定总体状态
|
274
|
-
overall_status = "healthy" if all("healthy" in status for status in components.values()) else "degraded"
|
275
|
-
|
276
|
-
return {
|
277
|
-
"status": overall_status,
|
278
|
-
"version": "2.0.0",
|
279
|
-
"uptime_seconds": round(uptime, 2),
|
280
|
-
"components": components,
|
281
|
-
"timestamp": datetime.now(timezone.utc).isoformat()
|
282
|
-
}
|
283
|
-
|
284
|
-
|
285
|
-
@app.get("/metrics")
|
286
|
-
async def get_metrics():
|
287
|
-
"""获取应用指标"""
|
288
|
-
uptime = time.time() - APP_START_TIME
|
289
|
-
|
290
|
-
# 缓存统计
|
291
|
-
cache_stats = cache_manager.get_stats()
|
292
|
-
|
293
|
-
# 系统指标
|
294
|
-
metrics = {
|
295
|
-
"uptime_seconds": round(uptime, 2),
|
296
|
-
"cache_stats": cache_stats,
|
297
|
-
"database_pools": {
|
298
|
-
"postgresql_pools": len(db_manager._pg_pools),
|
299
|
-
"redis_pools": len(db_manager._redis_pools),
|
300
|
-
"sqlalchemy_engines": len(db_manager._sqlalchemy_engines)
|
301
|
-
}
|
302
|
-
}
|
303
|
-
|
304
|
-
# 添加系统资源指标(如果psutil可用)
|
305
|
-
try:
|
306
|
-
import psutil
|
307
|
-
metrics["system"] = {
|
308
|
-
"cpu_percent": psutil.cpu_percent(interval=1),
|
309
|
-
"memory_percent": psutil.virtual_memory().percent,
|
310
|
-
"disk_percent": psutil.disk_usage('/').percent,
|
311
|
-
"process_count": len(psutil.pids())
|
312
|
-
}
|
313
|
-
except ImportError:
|
314
|
-
metrics["system"] = {"note": "psutil not available"}
|
315
|
-
|
316
|
-
return {
|
317
|
-
"success": True,
|
318
|
-
"data": metrics,
|
319
|
-
"timestamp": datetime.now(timezone.utc).isoformat()
|
320
|
-
}
|
321
|
-
|
322
|
-
|
323
|
-
# 注册API路由
|
324
|
-
|
325
|
-
# v1 API路由
|
326
|
-
app.include_router(v1_router, prefix="/api")
|
327
|
-
|
328
|
-
# 向后兼容的旧路由
|
329
|
-
app.include_router(namespace_router_old, prefix="/api")
|
330
|
-
app.include_router(backlog_router_old, prefix="/api")
|
331
|
-
|
332
|
-
# 简化的队列API路由(兼容性)
|
333
|
-
@app.get("/api/queues/{namespace}")
|
334
|
-
async def get_queues_legacy(namespace: str):
|
335
|
-
"""获取队列列表(兼容旧版本)"""
|
336
|
-
try:
|
337
|
-
from api.v1.queues import list_queues
|
338
|
-
from dependencies import get_validated_namespace, get_redis_client, get_pg_connection, get_namespace_connection, get_request_metrics
|
339
|
-
|
340
|
-
# 模拟依赖注入
|
341
|
-
validated_namespace = namespace
|
342
|
-
|
343
|
-
# 这里需要实际的依赖注入逻辑
|
344
|
-
# 暂时返回简化响应
|
345
|
-
return {
|
346
|
-
"success": True,
|
347
|
-
"data": [] # 返回空列表,实际应该调用新的API
|
348
|
-
}
|
349
|
-
except Exception as e:
|
350
|
-
logger.error(f"获取队列列表失败(兼容接口): {e}")
|
351
|
-
return {"success": False, "error": str(e)}
|
352
|
-
|
353
|
-
|
354
|
-
# 开发工具路由
|
355
|
-
if os.getenv("DEBUG", "false").lower() == "true":
|
356
|
-
@app.get("/debug/cache")
|
357
|
-
async def debug_cache():
|
358
|
-
"""调试缓存状态"""
|
359
|
-
return {
|
360
|
-
"stats": cache_manager.get_stats(),
|
361
|
-
"local_cache_keys": list(cache_manager.local_cache.keys())[:20], # 只显示前20个
|
362
|
-
"redis_connected": cache_manager.redis_client is not None
|
363
|
-
}
|
364
|
-
|
365
|
-
@app.post("/debug/cache/clear")
|
366
|
-
async def debug_clear_cache():
|
367
|
-
"""清空缓存"""
|
368
|
-
cleared = await cache_manager.clear_pattern("")
|
369
|
-
return {"cleared_items": cleared}
|
370
|
-
|
371
|
-
|
372
|
-
def run_server():
|
373
|
-
"""运行开发服务器"""
|
374
|
-
import uvicorn
|
375
|
-
|
376
|
-
port = int(os.getenv("PORT", "8002"))
|
377
|
-
host = os.getenv("HOST", "0.0.0.0")
|
378
|
-
reload = os.getenv("DEBUG", "false").lower() == "true"
|
379
|
-
|
380
|
-
logger.info(f"启动服务器: http://{host}:{port}")
|
381
|
-
logger.info(f"API文档: http://{host}:{port}/docs")
|
382
|
-
logger.info(f"调试模式: {reload}")
|
383
|
-
|
384
|
-
uvicorn.run(
|
385
|
-
"main_v2:app",
|
386
|
-
host=host,
|
387
|
-
port=port,
|
388
|
-
reload=reload,
|
389
|
-
log_level="info"
|
390
|
-
)
|
391
|
-
|
392
|
-
|
393
|
-
if __name__ == "__main__":
|
394
|
-
run_server()
|