jettask 0.2.15__py3-none-any.whl → 0.2.17__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.
Files changed (149) hide show
  1. jettask/__init__.py +14 -35
  2. jettask/{webui/__main__.py → __main__.py} +4 -4
  3. jettask/api/__init__.py +103 -0
  4. jettask/api/v1/__init__.py +29 -0
  5. jettask/api/v1/alerts.py +226 -0
  6. jettask/api/v1/analytics.py +323 -0
  7. jettask/api/v1/namespaces.py +134 -0
  8. jettask/api/v1/overview.py +136 -0
  9. jettask/api/v1/queues.py +530 -0
  10. jettask/api/v1/scheduled.py +420 -0
  11. jettask/api/v1/settings.py +44 -0
  12. jettask/{webui/api.py → api.py} +4 -46
  13. jettask/{webui/backend → backend}/main.py +21 -109
  14. jettask/{webui/backend → backend}/main_unified.py +1 -1
  15. jettask/{webui/backend → backend}/namespace_api_old.py +3 -30
  16. jettask/{webui/backend → backend}/namespace_data_access.py +2 -1
  17. jettask/{webui/backend → backend}/unified_api_router.py +14 -74
  18. jettask/{core/cli.py → cli.py} +106 -26
  19. jettask/config/nacos_config.py +386 -0
  20. jettask/core/app.py +8 -100
  21. jettask/core/db_manager.py +515 -0
  22. jettask/core/event_pool.py +5 -2
  23. jettask/core/unified_manager_base.py +59 -14
  24. jettask/{webui/db_init.py → db_init.py} +1 -1
  25. jettask/executors/asyncio.py +2 -2
  26. jettask/{webui/integrated_gradio_app.py → integrated_gradio_app.py} +1 -1
  27. jettask/{webui/multi_namespace_consumer.py → multi_namespace_consumer.py} +5 -2
  28. jettask/{webui/pg_consumer.py → pg_consumer.py} +137 -69
  29. jettask/{webui/run.py → run.py} +1 -1
  30. jettask/{webui/run_webui.py → run_webui.py} +4 -4
  31. jettask/scheduler/manager.py +6 -0
  32. jettask/scheduler/multi_namespace_scheduler.py +2 -2
  33. jettask/scheduler/unified_manager.py +5 -5
  34. jettask/scheduler/unified_scheduler_manager.py +20 -12
  35. jettask/schemas/__init__.py +166 -0
  36. jettask/schemas/alert.py +99 -0
  37. jettask/schemas/backlog.py +122 -0
  38. jettask/schemas/common.py +139 -0
  39. jettask/schemas/monitoring.py +181 -0
  40. jettask/schemas/namespace.py +168 -0
  41. jettask/schemas/queue.py +83 -0
  42. jettask/schemas/scheduled_task.py +128 -0
  43. jettask/schemas/task.py +70 -0
  44. jettask/services/__init__.py +24 -0
  45. jettask/services/alert_service.py +454 -0
  46. jettask/services/analytics_service.py +46 -0
  47. jettask/services/overview_service.py +978 -0
  48. jettask/services/queue_service.py +711 -0
  49. jettask/services/redis_monitor_service.py +151 -0
  50. jettask/services/scheduled_task_service.py +207 -0
  51. jettask/services/settings_service.py +758 -0
  52. jettask/services/task_service.py +157 -0
  53. jettask/{webui/task_center.py → task_center.py} +30 -8
  54. jettask/{webui/task_center_client.py → task_center_client.py} +1 -1
  55. jettask/{webui/config.py → webui_config.py} +6 -1
  56. jettask/webui_exceptions.py +67 -0
  57. jettask/webui_sql/verify_database.sql +72 -0
  58. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/METADATA +2 -1
  59. jettask-0.2.17.dist-info/RECORD +150 -0
  60. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/entry_points.txt +1 -1
  61. jettask/webui/backend/data_api.py +0 -3294
  62. jettask/webui/backend/namespace_api.py +0 -295
  63. jettask/webui/backend/queue_backlog_api.py +0 -727
  64. jettask/webui/backend/redis_monitor_api.py +0 -476
  65. jettask/webui/frontend/index.html +0 -13
  66. jettask/webui/frontend/package.json +0 -30
  67. jettask/webui/frontend/src/App.css +0 -109
  68. jettask/webui/frontend/src/App.jsx +0 -66
  69. jettask/webui/frontend/src/components/NamespaceSelector.jsx +0 -166
  70. jettask/webui/frontend/src/components/QueueBacklogChart.jsx +0 -298
  71. jettask/webui/frontend/src/components/QueueBacklogTrend.jsx +0 -638
  72. jettask/webui/frontend/src/components/QueueDetailsTable.css +0 -65
  73. jettask/webui/frontend/src/components/QueueDetailsTable.jsx +0 -487
  74. jettask/webui/frontend/src/components/QueueDetailsTableV2.jsx +0 -465
  75. jettask/webui/frontend/src/components/ScheduledTaskFilter.jsx +0 -423
  76. jettask/webui/frontend/src/components/TaskFilter.jsx +0 -425
  77. jettask/webui/frontend/src/components/TimeRangeSelector.css +0 -21
  78. jettask/webui/frontend/src/components/TimeRangeSelector.jsx +0 -160
  79. jettask/webui/frontend/src/components/charts/QueueChart.jsx +0 -111
  80. jettask/webui/frontend/src/components/charts/QueueTrendChart.jsx +0 -115
  81. jettask/webui/frontend/src/components/charts/WorkerChart.jsx +0 -40
  82. jettask/webui/frontend/src/components/common/StatsCard.jsx +0 -18
  83. jettask/webui/frontend/src/components/layout/AppLayout.css +0 -95
  84. jettask/webui/frontend/src/components/layout/AppLayout.jsx +0 -49
  85. jettask/webui/frontend/src/components/layout/Header.css +0 -106
  86. jettask/webui/frontend/src/components/layout/Header.jsx +0 -106
  87. jettask/webui/frontend/src/components/layout/SideMenu.css +0 -137
  88. jettask/webui/frontend/src/components/layout/SideMenu.jsx +0 -209
  89. jettask/webui/frontend/src/components/layout/TabsNav.css +0 -244
  90. jettask/webui/frontend/src/components/layout/TabsNav.jsx +0 -206
  91. jettask/webui/frontend/src/components/layout/UserInfo.css +0 -197
  92. jettask/webui/frontend/src/components/layout/UserInfo.jsx +0 -197
  93. jettask/webui/frontend/src/contexts/LoadingContext.jsx +0 -27
  94. jettask/webui/frontend/src/contexts/NamespaceContext.jsx +0 -72
  95. jettask/webui/frontend/src/contexts/TabsContext.backup.jsx +0 -245
  96. jettask/webui/frontend/src/index.css +0 -114
  97. jettask/webui/frontend/src/main.jsx +0 -22
  98. jettask/webui/frontend/src/pages/Alerts.jsx +0 -684
  99. jettask/webui/frontend/src/pages/Dashboard/index.css +0 -35
  100. jettask/webui/frontend/src/pages/Dashboard/index.jsx +0 -281
  101. jettask/webui/frontend/src/pages/Dashboard.jsx +0 -1330
  102. jettask/webui/frontend/src/pages/QueueDetail.jsx +0 -1117
  103. jettask/webui/frontend/src/pages/QueueMonitor.jsx +0 -527
  104. jettask/webui/frontend/src/pages/Queues.jsx +0 -12
  105. jettask/webui/frontend/src/pages/ScheduledTasks.jsx +0 -810
  106. jettask/webui/frontend/src/pages/Settings.jsx +0 -801
  107. jettask/webui/frontend/src/pages/Workers.jsx +0 -12
  108. jettask/webui/frontend/src/services/api.js +0 -159
  109. jettask/webui/frontend/src/services/queueTrend.js +0 -166
  110. jettask/webui/frontend/src/utils/suppressWarnings.js +0 -22
  111. jettask/webui/frontend/src/utils/userPreferences.js +0 -154
  112. jettask/webui/frontend/vite.config.js +0 -26
  113. jettask/webui/sql/init_database.sql +0 -640
  114. jettask-0.2.15.dist-info/RECORD +0 -172
  115. /jettask/{webui/backend → backend}/__init__.py +0 -0
  116. /jettask/{webui/backend → backend}/api/__init__.py +0 -0
  117. /jettask/{webui/backend → backend}/api/v1/__init__.py +0 -0
  118. /jettask/{webui/backend → backend}/api/v1/monitoring.py +0 -0
  119. /jettask/{webui/backend → backend}/api/v1/namespaces.py +0 -0
  120. /jettask/{webui/backend → backend}/api/v1/queues.py +0 -0
  121. /jettask/{webui/backend → backend}/api/v1/tasks.py +0 -0
  122. /jettask/{webui/backend → backend}/config.py +0 -0
  123. /jettask/{webui/backend → backend}/core/__init__.py +0 -0
  124. /jettask/{webui/backend → backend}/core/cache.py +0 -0
  125. /jettask/{webui/backend → backend}/core/database.py +0 -0
  126. /jettask/{webui/backend → backend}/core/exceptions.py +0 -0
  127. /jettask/{webui/backend → backend}/data_access.py +0 -0
  128. /jettask/{webui/backend → backend}/dependencies.py +0 -0
  129. /jettask/{webui/backend → backend}/init_meta_db.py +0 -0
  130. /jettask/{webui/backend → backend}/main_v2.py +0 -0
  131. /jettask/{webui/backend → backend}/models/__init__.py +0 -0
  132. /jettask/{webui/backend → backend}/models/requests.py +0 -0
  133. /jettask/{webui/backend → backend}/models/responses.py +0 -0
  134. /jettask/{webui/backend → backend}/queue_stats_v2.py +0 -0
  135. /jettask/{webui/backend → backend}/services/__init__.py +0 -0
  136. /jettask/{webui/backend → backend}/start.py +0 -0
  137. /jettask/{webui/cleanup_deprecated_tables.sql → cleanup_deprecated_tables.sql} +0 -0
  138. /jettask/{webui/gradio_app.py → gradio_app.py} +0 -0
  139. /jettask/{webui/__init__.py → main.py} +0 -0
  140. /jettask/{webui/models.py → models.py} +0 -0
  141. /jettask/{webui/run_monitor.py → run_monitor.py} +0 -0
  142. /jettask/{webui/schema.sql → schema.sql} +0 -0
  143. /jettask/{webui/unified_consumer_manager.py → unified_consumer_manager.py} +0 -0
  144. /jettask/{webui/models → webui_models}/__init__.py +0 -0
  145. /jettask/{webui/models → webui_models}/namespace.py +0 -0
  146. /jettask/{webui/sql → webui_sql}/batch_upsert_functions.sql +0 -0
  147. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/WHEEL +0 -0
  148. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/licenses/LICENSE +0 -0
  149. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,168 @@
1
+ """
2
+ 命名空间相关的数据模型
3
+ """
4
+ from typing import Optional, Dict, Any, List
5
+ from datetime import datetime
6
+ from pydantic import BaseModel, Field
7
+ from enum import Enum
8
+
9
+
10
+ class ConfigMode(str, Enum):
11
+ """配置模式枚举"""
12
+ DIRECT = "direct" # 直接配置模式(自由输入)
13
+ NACOS = "nacos" # Nacos配置模式
14
+
15
+
16
+ class NamespaceCreate(BaseModel):
17
+ """创建命名空间请求模型"""
18
+ name: str = Field(..., description="命名空间名称")
19
+ description: Optional[str] = Field(None, description="命名空间描述")
20
+
21
+ # 配置模式
22
+ config_mode: ConfigMode = Field(ConfigMode.DIRECT, description="配置模式: direct(直接配置) 或 nacos(Nacos配置)")
23
+
24
+ # Redis配置 - 支持两种方式
25
+ # 方式1: 直接配置字符串 (格式: redis://[password@]host:port/db)
26
+ redis_url: Optional[str] = Field(None, description="Redis连接字符串,格式: redis://[password@]host:port/db")
27
+ # 方式2: Nacos配置键
28
+ redis_nacos_key: Optional[str] = Field(None, description="Redis连接字符串的Nacos配置键")
29
+
30
+ # PostgreSQL配置 - 支持两种方式
31
+ # 方式1: 直接配置字符串 (格式: postgresql://user:password@host:port/database)
32
+ pg_url: Optional[str] = Field(None, description="PostgreSQL连接字符串,格式: postgresql://user:password@host:port/database")
33
+ # 方式2: Nacos配置键
34
+ pg_nacos_key: Optional[str] = Field(None, description="PostgreSQL连接字符串的Nacos配置键")
35
+
36
+
37
+ class NamespaceUpdate(BaseModel):
38
+ """更新命名空间请求模型"""
39
+ description: Optional[str] = Field(None, description="命名空间描述")
40
+
41
+ # 配置模式
42
+ config_mode: Optional[ConfigMode] = Field(None, description="配置模式: direct(直接配置) 或 nacos(Nacos配置)")
43
+
44
+ # Redis配置 - 支持两种方式
45
+ redis_url: Optional[str] = Field(None, description="Redis连接字符串,格式: redis://[password@]host:port/db")
46
+ redis_nacos_key: Optional[str] = Field(None, description="Redis连接字符串的Nacos配置键")
47
+
48
+ # PostgreSQL配置 - 支持两种方式
49
+ pg_url: Optional[str] = Field(None, description="PostgreSQL连接字符串,格式: postgresql://user:password@host:port/database")
50
+ pg_nacos_key: Optional[str] = Field(None, description="PostgreSQL连接字符串的Nacos配置键")
51
+
52
+ enabled: Optional[bool] = Field(None, description="是否启用")
53
+
54
+
55
+ class NamespaceResponse(BaseModel):
56
+ """命名空间响应模型"""
57
+ name: str = Field(..., description="命名空间名称")
58
+ description: Optional[str] = Field(None, description="命名空间描述")
59
+
60
+ # Redis配置信息 - 只返回最终的URL
61
+ redis_url: str = Field(..., description="Redis连接字符串")
62
+
63
+ # PostgreSQL配置信息 - 只返回最终的URL
64
+ pg_url: Optional[str] = Field(None, description="PostgreSQL连接字符串")
65
+
66
+ # 连接信息
67
+ connection_url: str = Field(..., description="用于连接此命名空间的URL路径")
68
+ version: int = Field(default=1, description="配置版本号")
69
+
70
+ enabled: bool = Field(..., description="是否启用")
71
+ created_at: datetime = Field(..., description="创建时间")
72
+ updated_at: Optional[datetime] = Field(None, description="更新时间")
73
+
74
+ class Config:
75
+ json_encoders = {
76
+ datetime: lambda v: v.isoformat() if v else None
77
+ }
78
+
79
+
80
+ class NamespaceInfo(BaseModel):
81
+ """命名空间详细信息模型"""
82
+ name: str = Field(..., description="命名空间名称")
83
+ description: Optional[str] = Field(None, description="命名空间描述")
84
+ redis_config: Dict[str, Any] = Field(..., description="Redis配置")
85
+ status: str = Field(..., description="状态")
86
+ enabled: bool = Field(default=True, description="是否启用")
87
+ created_at: datetime = Field(..., description="创建时间")
88
+ updated_at: Optional[datetime] = Field(None, description="更新时间")
89
+ last_activity: Optional[datetime] = Field(None, description="最后活动时间")
90
+
91
+ # 统计信息
92
+ total_queues: int = Field(default=0, description="总队列数")
93
+ total_tasks: int = Field(default=0, description="总任务数")
94
+ active_workers: int = Field(default=0, description="活跃工作节点数")
95
+ pending_tasks: int = Field(default=0, description="待处理任务数")
96
+ processing_tasks: int = Field(default=0, description="处理中任务数")
97
+ completed_tasks: int = Field(default=0, description="已完成任务数")
98
+ failed_tasks: int = Field(default=0, description="失败任务数")
99
+
100
+ class Config:
101
+ json_encoders = {
102
+ datetime: lambda v: v.isoformat() if v else None
103
+ }
104
+
105
+
106
+ class NamespaceCreateRequest(BaseModel):
107
+ """命名空间创建请求模型(详细版)"""
108
+ name: str = Field(..., min_length=1, max_length=100, description="命名空间名称")
109
+ display_name: Optional[str] = Field(None, max_length=200, description="显示名称")
110
+ description: Optional[str] = Field(None, max_length=1000, description="命名空间描述")
111
+
112
+ # Redis连接配置
113
+ redis_host: str = Field(..., description="Redis主机地址")
114
+ redis_port: int = Field(..., ge=1, le=65535, description="Redis端口号")
115
+ redis_db: int = Field(default=0, ge=0, le=15, description="Redis数据库编号")
116
+ redis_password: Optional[str] = Field(None, description="Redis密码")
117
+ redis_ssl: bool = Field(default=False, description="是否使用SSL连接")
118
+ redis_ssl_cert_reqs: Optional[str] = Field(None, description="SSL证书验证")
119
+ redis_ssl_ca_certs: Optional[str] = Field(None, description="SSL CA证书路径")
120
+ redis_ssl_certfile: Optional[str] = Field(None, description="SSL客户端证书路径")
121
+ redis_ssl_keyfile: Optional[str] = Field(None, description="SSL私钥路径")
122
+
123
+ # 连接池配置
124
+ redis_max_connections: int = Field(default=50, ge=1, le=1000, description="最大连接数")
125
+ redis_connection_timeout: int = Field(default=30, ge=1, description="连接超时(秒)")
126
+ redis_socket_timeout: int = Field(default=30, ge=1, description="套接字超时(秒)")
127
+
128
+ # 业务配置
129
+ default_queue_prefix: str = Field(default="task", description="默认队列前缀")
130
+ max_queue_size: Optional[int] = Field(None, ge=1, description="队列最大大小")
131
+ task_ttl: int = Field(default=86400, ge=60, description="任务TTL(秒)")
132
+ result_ttl: int = Field(default=3600, ge=60, description="结果TTL(秒)")
133
+
134
+ # 其他设置
135
+ enabled: bool = Field(default=True, description="是否启用")
136
+ auto_create_queues: bool = Field(default=True, description="是否自动创建队列")
137
+ tags: List[str] = Field(default=[], description="标签列表")
138
+ metadata: Dict[str, Any] = Field(default={}, description="元数据")
139
+
140
+
141
+ class NamespaceUpdateRequest(BaseModel):
142
+ """命名空间更新请求模型(详细版)"""
143
+ display_name: Optional[str] = Field(None, max_length=200, description="显示名称")
144
+ description: Optional[str] = Field(None, max_length=1000, description="命名空间描述")
145
+
146
+ # Redis连接配置
147
+ redis_host: Optional[str] = Field(None, description="Redis主机地址")
148
+ redis_port: Optional[int] = Field(None, ge=1, le=65535, description="Redis端口号")
149
+ redis_db: Optional[int] = Field(None, ge=0, le=15, description="Redis数据库编号")
150
+ redis_password: Optional[str] = Field(None, description="Redis密码")
151
+ redis_ssl: Optional[bool] = Field(None, description="是否使用SSL连接")
152
+
153
+ # 连接池配置
154
+ redis_max_connections: Optional[int] = Field(None, ge=1, le=1000, description="最大连接数")
155
+ redis_connection_timeout: Optional[int] = Field(None, ge=1, description="连接超时(秒)")
156
+ redis_socket_timeout: Optional[int] = Field(None, ge=1, description="套接字超时(秒)")
157
+
158
+ # 业务配置
159
+ default_queue_prefix: Optional[str] = Field(None, description="默认队列前缀")
160
+ max_queue_size: Optional[int] = Field(None, ge=1, description="队列最大大小")
161
+ task_ttl: Optional[int] = Field(None, ge=60, description="任务TTL(秒)")
162
+ result_ttl: Optional[int] = Field(None, ge=60, description="结果TTL(秒)")
163
+
164
+ # 其他设置
165
+ enabled: Optional[bool] = Field(None, description="是否启用")
166
+ auto_create_queues: Optional[bool] = Field(None, description="是否自动创建队列")
167
+ tags: Optional[List[str]] = Field(None, description="标签列表")
168
+ metadata: Optional[Dict[str, Any]] = Field(None, description="元数据")
@@ -0,0 +1,83 @@
1
+ """
2
+ 队列相关的数据模型
3
+ """
4
+ from typing import Optional, List, Dict, Any
5
+ from datetime import datetime
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class TimeRangeQuery(BaseModel):
10
+ """时间范围查询模型"""
11
+ queues: Optional[List[str]] = Field(None, description="队列名称列表,为空时统计所有队列")
12
+ time_range: Optional[str] = Field(None, description="时间范围(如 '1h', '24h', '7d'),与 start_time/end_time 二选一")
13
+ start_time: Optional[str] = Field(None, description="开始时间,与 time_range 二选一")
14
+ end_time: Optional[str] = Field(None, description="结束时间,与 time_range 二选一")
15
+ interval: Optional[str] = Field(default="1h", description="时间间隔")
16
+
17
+
18
+ class QueueStatsResponse(BaseModel):
19
+ """队列统计响应模型"""
20
+ queue_name: str = Field(..., description="队列名称")
21
+ pending_count: int = Field(default=0, description="待处理任务数")
22
+ processing_count: int = Field(default=0, description="处理中任务数")
23
+ completed_count: int = Field(default=0, description="已完成任务数")
24
+ failed_count: int = Field(default=0, description="失败任务数")
25
+ success_rate: float = Field(default=0.0, description="成功率")
26
+ avg_processing_time: Optional[float] = Field(None, description="平均处理时间")
27
+
28
+
29
+ class QueueTimelineResponse(BaseModel):
30
+ """队列时间线响应模型"""
31
+ queue_name: str = Field(..., description="队列名称")
32
+ timeline: List[Dict[str, Any]] = Field(default=[], description="时间线数据")
33
+
34
+
35
+ class TrimQueueRequest(BaseModel):
36
+ """修剪队列请求模型"""
37
+ queue_name: str = Field(..., description="队列名称")
38
+ max_length: int = Field(..., ge=1, description="最大长度")
39
+ trim_strategy: str = Field(default="oldest", description="修剪策略", pattern="^(oldest|newest)$")
40
+
41
+
42
+ class QueueInfo(BaseModel):
43
+ """队列信息模型"""
44
+ name: str = Field(..., description="队列名称")
45
+ namespace: str = Field(..., description="命名空间")
46
+ pending_count: int = Field(default=0, description="待处理任务数")
47
+ processing_count: int = Field(default=0, description="处理中任务数")
48
+ completed_count: int = Field(default=0, description="已完成任务数")
49
+ failed_count: int = Field(default=0, description="失败任务数")
50
+ created_at: Optional[datetime] = Field(None, description="创建时间")
51
+ updated_at: Optional[datetime] = Field(None, description="更新时间")
52
+
53
+ class Config:
54
+ json_encoders = {
55
+ datetime: lambda v: v.isoformat() if v else None
56
+ }
57
+
58
+
59
+ class QueueStats(BaseModel):
60
+ """队列统计模型"""
61
+ queue_name: str = Field(..., description="队列名称")
62
+ total_tasks: int = Field(default=0, description="总任务数")
63
+ pending_tasks: int = Field(default=0, description="待处理任务数")
64
+ processing_tasks: int = Field(default=0, description="处理中任务数")
65
+ completed_tasks: int = Field(default=0, description="已完成任务数")
66
+ failed_tasks: int = Field(default=0, description="失败任务数")
67
+ success_rate: float = Field(default=0.0, description="成功率")
68
+ avg_processing_time: Optional[float] = Field(None, description="平均处理时间")
69
+ throughput: Optional[float] = Field(None, description="吞吐量(任务/秒)")
70
+ last_activity: Optional[datetime] = Field(None, description="最后活动时间")
71
+
72
+ class Config:
73
+ json_encoders = {
74
+ datetime: lambda v: v.isoformat() if v else None
75
+ }
76
+
77
+
78
+ class QueueActionRequest(BaseModel):
79
+ """队列操作请求模型"""
80
+ queue_names: List[str] = Field(..., min_items=1, description="队列名称列表")
81
+ action: str = Field(..., description="操作类型", pattern="^(pause|resume|clear|delete)$")
82
+ reason: Optional[str] = Field(None, description="操作原因")
83
+ force: bool = Field(default=False, description="是否强制执行")
@@ -0,0 +1,128 @@
1
+ """
2
+ 定时任务相关的数据模型
3
+ """
4
+ from typing import Optional, Dict, Any
5
+ from datetime import datetime
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class ScheduleConfig(BaseModel):
10
+ """调度配置模型"""
11
+ schedule_type: str = Field(..., description="调度类型", pattern="^(cron|interval)$")
12
+ cron_expression: Optional[str] = Field(None, description="Cron表达式(当schedule_type为cron时)")
13
+ interval_seconds: Optional[int] = Field(None, ge=1, description="间隔秒数(当schedule_type为interval时)")
14
+ timezone: str = Field(default="UTC", description="时区")
15
+ max_instances: int = Field(default=1, ge=1, description="最大实例数")
16
+
17
+ def validate_schedule_config(self):
18
+ """验证调度配置"""
19
+ if self.schedule_type == "cron" and not self.cron_expression:
20
+ raise ValueError("Cron类型调度必须提供cron_expression")
21
+ if self.schedule_type == "interval" and not self.interval_seconds:
22
+ raise ValueError("Interval类型调度必须提供interval_seconds")
23
+
24
+
25
+ class ScheduledTaskRequest(BaseModel):
26
+ """定时任务请求模型"""
27
+ task_name: str = Field(..., description="任务名称")
28
+ task_function: str = Field(..., description="任务函数")
29
+ schedule_config: ScheduleConfig = Field(..., description="调度配置")
30
+ task_args: Optional[list] = Field(default=[], description="任务参数")
31
+ task_kwargs: Optional[Dict[str, Any]] = Field(default={}, description="任务关键字参数")
32
+ queue_name: Optional[str] = Field(None, description="队列名称")
33
+ priority: int = Field(default=0, description="优先级")
34
+ enabled: bool = Field(default=True, description="是否启用")
35
+ description: Optional[str] = Field(None, description="任务描述")
36
+
37
+
38
+ class ScheduledTaskCreate(BaseModel):
39
+ """创建定时任务请求模型"""
40
+ name: str = Field(..., description="任务名称")
41
+ task_function: str = Field(..., description="任务函数")
42
+ schedule_type: str = Field(..., description="调度类型", pattern="^(cron|interval)$")
43
+ cron_expression: Optional[str] = Field(None, description="Cron表达式")
44
+ interval_seconds: Optional[int] = Field(None, ge=1, description="间隔秒数")
45
+ task_args: Optional[list] = Field(default=[], description="任务参数")
46
+ task_kwargs: Optional[Dict[str, Any]] = Field(default={}, description="任务关键字参数")
47
+ enabled: bool = Field(default=True, description="是否启用")
48
+ description: Optional[str] = Field(None, description="任务描述")
49
+
50
+
51
+ class ScheduledTaskUpdate(BaseModel):
52
+ """更新定时任务请求模型"""
53
+ name: Optional[str] = Field(None, description="任务名称")
54
+ task_function: Optional[str] = Field(None, description="任务函数")
55
+ schedule_type: Optional[str] = Field(None, description="调度类型")
56
+ cron_expression: Optional[str] = Field(None, description="Cron表达式")
57
+ interval_seconds: Optional[int] = Field(None, ge=1, description="间隔秒数")
58
+ task_args: Optional[list] = Field(None, description="任务参数")
59
+ task_kwargs: Optional[Dict[str, Any]] = Field(None, description="任务关键字参数")
60
+ enabled: Optional[bool] = Field(None, description="是否启用")
61
+ description: Optional[str] = Field(None, description="任务描述")
62
+
63
+
64
+ class ScheduledTaskCreateRequest(BaseModel):
65
+ """定时任务创建请求模型(详细版)"""
66
+ task_name: str = Field(..., min_length=1, max_length=255, description="任务名称")
67
+ task_function: str = Field(..., min_length=1, description="任务函数路径")
68
+ schedule_type: str = Field(..., description="调度类型", pattern="^(cron|interval|once)$")
69
+ cron_expression: Optional[str] = Field(None, description="Cron表达式")
70
+ interval_seconds: Optional[int] = Field(None, ge=1, le=86400*365, description="间隔秒数")
71
+ start_time: Optional[datetime] = Field(None, description="开始时间")
72
+ end_time: Optional[datetime] = Field(None, description="结束时间")
73
+ task_args: list = Field(default=[], description="任务参数")
74
+ task_kwargs: Dict[str, Any] = Field(default={}, description="任务关键字参数")
75
+ queue_name: Optional[str] = Field(None, description="目标队列")
76
+ priority: int = Field(default=0, ge=0, le=100, description="优先级")
77
+ max_retries: int = Field(default=3, ge=0, le=10, description="最大重试次数")
78
+ timeout: Optional[int] = Field(None, ge=1, description="超时时间(秒)")
79
+ enabled: bool = Field(default=True, description="是否启用")
80
+ description: Optional[str] = Field(None, max_length=1000, description="任务描述")
81
+
82
+
83
+ class ScheduledTaskResponse(BaseModel):
84
+ """定时任务响应模型"""
85
+ id: str = Field(..., description="任务ID")
86
+ task_name: str = Field(..., description="任务名称")
87
+ task_function: str = Field(..., description="任务函数")
88
+ schedule_type: str = Field(..., description="调度类型")
89
+ next_run_time: Optional[datetime] = Field(None, description="下次运行时间")
90
+ last_run_time: Optional[datetime] = Field(None, description="上次运行时间")
91
+ status: str = Field(..., description="任务状态")
92
+ enabled: bool = Field(..., description="是否启用")
93
+
94
+ class Config:
95
+ json_encoders = {
96
+ datetime: lambda v: v.isoformat() if v else None
97
+ }
98
+
99
+
100
+ class ScheduledTaskInfo(BaseModel):
101
+ """定时任务详细信息模型"""
102
+ id: str = Field(..., description="任务ID")
103
+ task_name: str = Field(..., description="任务名称")
104
+ task_function: str = Field(..., description="任务函数")
105
+ schedule_type: str = Field(..., description="调度类型")
106
+ cron_expression: Optional[str] = Field(None, description="Cron表达式")
107
+ interval_seconds: Optional[int] = Field(None, description="间隔秒数")
108
+ task_args: list = Field(default=[], description="任务参数")
109
+ task_kwargs: Dict[str, Any] = Field(default={}, description="任务关键字参数")
110
+ queue_name: Optional[str] = Field(None, description="队列名称")
111
+ priority: int = Field(default=0, description="优先级")
112
+ max_retries: int = Field(default=3, description="最大重试次数")
113
+ timeout: Optional[int] = Field(None, description="超时时间")
114
+ enabled: bool = Field(default=True, description="是否启用")
115
+ status: str = Field(..., description="任务状态")
116
+ created_at: datetime = Field(..., description="创建时间")
117
+ updated_at: Optional[datetime] = Field(None, description="更新时间")
118
+ next_run_time: Optional[datetime] = Field(None, description="下次运行时间")
119
+ last_run_time: Optional[datetime] = Field(None, description="上次运行时间")
120
+ run_count: int = Field(default=0, description="运行次数")
121
+ success_count: int = Field(default=0, description="成功次数")
122
+ failure_count: int = Field(default=0, description="失败次数")
123
+ description: Optional[str] = Field(None, description="任务描述")
124
+
125
+ class Config:
126
+ json_encoders = {
127
+ datetime: lambda v: v.isoformat() if v else None
128
+ }
@@ -0,0 +1,70 @@
1
+ """
2
+ 任务相关的数据模型
3
+ """
4
+ from typing import Optional, List, Dict, Any
5
+ from datetime import datetime
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class TasksRequest(BaseModel):
10
+ """任务查询请求模型"""
11
+ queue_name: str = Field(..., description="队列名称")
12
+ page: int = Field(default=1, ge=1, description="页码")
13
+ page_size: int = Field(default=20, ge=1, le=100, description="每页大小")
14
+ filters: Optional[List[Dict]] = Field(default=[], description="筛选条件")
15
+ time_range: Optional[str] = Field(None, description="时间范围,如 '15m', '1h', '7d'")
16
+ start_time: Optional[str] = Field(None, description="开始时间")
17
+ end_time: Optional[str] = Field(None, description="结束时间")
18
+
19
+
20
+ class TaskInfo(BaseModel):
21
+ """任务信息模型"""
22
+ id: str = Field(..., description="任务ID")
23
+ queue_name: str = Field(..., description="队列名称")
24
+ status: str = Field(..., description="任务状态")
25
+ created_at: datetime = Field(..., description="创建时间")
26
+ started_at: Optional[datetime] = Field(None, description="开始时间")
27
+ completed_at: Optional[datetime] = Field(None, description="完成时间")
28
+ worker_id: Optional[str] = Field(None, description="工作节点ID")
29
+ task_name: Optional[str] = Field(None, description="任务名称")
30
+ task_data: Optional[Dict[str, Any]] = Field(None, description="任务数据")
31
+ result: Optional[Any] = Field(None, description="任务结果")
32
+ error: Optional[str] = Field(None, description="错误信息")
33
+ retry_count: int = Field(default=0, description="重试次数")
34
+ execution_time: Optional[float] = Field(None, description="执行时间(秒)")
35
+ priority: Optional[int] = Field(None, description="优先级")
36
+ consumer_group: Optional[str] = Field(None, description="消费者组")
37
+
38
+ class Config:
39
+ json_encoders = {
40
+ datetime: lambda v: v.isoformat() if v else None
41
+ }
42
+
43
+
44
+ class TaskDetailResponse(BaseModel):
45
+ """任务详细信息响应模型"""
46
+ success: bool = Field(default=True, description="请求是否成功")
47
+ data: Optional[TaskInfo] = Field(None, description="任务详细信息")
48
+ error: Optional[str] = Field(None, description="错误信息")
49
+
50
+ class Config:
51
+ json_encoders = {
52
+ datetime: lambda v: v.isoformat() if v else None
53
+ }
54
+
55
+
56
+ class TaskActionRequest(BaseModel):
57
+ """任务操作请求模型"""
58
+ task_ids: List[str] = Field(..., min_items=1, description="任务ID列表")
59
+ action: str = Field(..., description="操作类型", pattern="^(retry|cancel|delete)$")
60
+ reason: Optional[str] = Field(None, description="操作原因")
61
+
62
+
63
+ class TaskListResponse(BaseModel):
64
+ """任务列表响应模型"""
65
+ success: bool = Field(default=True, description="请求是否成功")
66
+ data: List[TaskInfo] = Field(default=[], description="任务列表")
67
+ total: int = Field(default=0, description="总记录数")
68
+ page: int = Field(default=1, description="当前页码")
69
+ page_size: int = Field(default=20, description="每页大小")
70
+ error: Optional[str] = Field(None, description="错误信息")
@@ -0,0 +1,24 @@
1
+ """
2
+ 业务逻辑服务层
3
+ 包含所有业务逻辑处理
4
+ """
5
+
6
+ from .overview_service import OverviewService
7
+ from .queue_service import QueueService
8
+ from .scheduled_task_service import ScheduledTaskService
9
+ from .alert_service import AlertService
10
+ from .analytics_service import AnalyticsService
11
+ from .settings_service import SettingsService
12
+ from .task_service import TaskService
13
+ from .redis_monitor_service import RedisMonitorService
14
+
15
+ __all__ = [
16
+ 'OverviewService',
17
+ 'QueueService',
18
+ 'ScheduledTaskService',
19
+ 'AlertService',
20
+ 'AnalyticsService',
21
+ 'SettingsService',
22
+ 'TaskService',
23
+ 'RedisMonitorService'
24
+ ]