jettask 0.2.14__py3-none-any.whl → 0.2.16__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 (148) 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 +47 -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/multi_namespace_scheduler.py +2 -2
  32. jettask/scheduler/unified_manager.py +5 -5
  33. jettask/scheduler/unified_scheduler_manager.py +1 -1
  34. jettask/schemas/__init__.py +166 -0
  35. jettask/schemas/alert.py +99 -0
  36. jettask/schemas/backlog.py +122 -0
  37. jettask/schemas/common.py +139 -0
  38. jettask/schemas/monitoring.py +181 -0
  39. jettask/schemas/namespace.py +168 -0
  40. jettask/schemas/queue.py +83 -0
  41. jettask/schemas/scheduled_task.py +128 -0
  42. jettask/schemas/task.py +70 -0
  43. jettask/services/__init__.py +24 -0
  44. jettask/services/alert_service.py +454 -0
  45. jettask/services/analytics_service.py +46 -0
  46. jettask/services/overview_service.py +978 -0
  47. jettask/services/queue_service.py +711 -0
  48. jettask/services/redis_monitor_service.py +151 -0
  49. jettask/services/scheduled_task_service.py +207 -0
  50. jettask/services/settings_service.py +758 -0
  51. jettask/services/task_service.py +157 -0
  52. jettask/{webui/task_center.py → task_center.py} +30 -8
  53. jettask/{webui/task_center_client.py → task_center_client.py} +1 -1
  54. jettask/{webui/config.py → webui_config.py} +6 -1
  55. jettask/webui_exceptions.py +67 -0
  56. jettask/webui_sql/verify_database.sql +72 -0
  57. {jettask-0.2.14.dist-info → jettask-0.2.16.dist-info}/METADATA +3 -1
  58. jettask-0.2.16.dist-info/RECORD +150 -0
  59. {jettask-0.2.14.dist-info → jettask-0.2.16.dist-info}/entry_points.txt +1 -1
  60. jettask/webui/backend/data_api.py +0 -3294
  61. jettask/webui/backend/namespace_api.py +0 -295
  62. jettask/webui/backend/queue_backlog_api.py +0 -727
  63. jettask/webui/backend/redis_monitor_api.py +0 -476
  64. jettask/webui/frontend/index.html +0 -13
  65. jettask/webui/frontend/package.json +0 -30
  66. jettask/webui/frontend/src/App.css +0 -109
  67. jettask/webui/frontend/src/App.jsx +0 -66
  68. jettask/webui/frontend/src/components/NamespaceSelector.jsx +0 -166
  69. jettask/webui/frontend/src/components/QueueBacklogChart.jsx +0 -298
  70. jettask/webui/frontend/src/components/QueueBacklogTrend.jsx +0 -638
  71. jettask/webui/frontend/src/components/QueueDetailsTable.css +0 -65
  72. jettask/webui/frontend/src/components/QueueDetailsTable.jsx +0 -487
  73. jettask/webui/frontend/src/components/QueueDetailsTableV2.jsx +0 -465
  74. jettask/webui/frontend/src/components/ScheduledTaskFilter.jsx +0 -423
  75. jettask/webui/frontend/src/components/TaskFilter.jsx +0 -425
  76. jettask/webui/frontend/src/components/TimeRangeSelector.css +0 -21
  77. jettask/webui/frontend/src/components/TimeRangeSelector.jsx +0 -160
  78. jettask/webui/frontend/src/components/charts/QueueChart.jsx +0 -111
  79. jettask/webui/frontend/src/components/charts/QueueTrendChart.jsx +0 -115
  80. jettask/webui/frontend/src/components/charts/WorkerChart.jsx +0 -40
  81. jettask/webui/frontend/src/components/common/StatsCard.jsx +0 -18
  82. jettask/webui/frontend/src/components/layout/AppLayout.css +0 -95
  83. jettask/webui/frontend/src/components/layout/AppLayout.jsx +0 -49
  84. jettask/webui/frontend/src/components/layout/Header.css +0 -106
  85. jettask/webui/frontend/src/components/layout/Header.jsx +0 -106
  86. jettask/webui/frontend/src/components/layout/SideMenu.css +0 -137
  87. jettask/webui/frontend/src/components/layout/SideMenu.jsx +0 -209
  88. jettask/webui/frontend/src/components/layout/TabsNav.css +0 -244
  89. jettask/webui/frontend/src/components/layout/TabsNav.jsx +0 -206
  90. jettask/webui/frontend/src/components/layout/UserInfo.css +0 -197
  91. jettask/webui/frontend/src/components/layout/UserInfo.jsx +0 -197
  92. jettask/webui/frontend/src/contexts/LoadingContext.jsx +0 -27
  93. jettask/webui/frontend/src/contexts/NamespaceContext.jsx +0 -72
  94. jettask/webui/frontend/src/contexts/TabsContext.backup.jsx +0 -245
  95. jettask/webui/frontend/src/index.css +0 -114
  96. jettask/webui/frontend/src/main.jsx +0 -22
  97. jettask/webui/frontend/src/pages/Alerts.jsx +0 -684
  98. jettask/webui/frontend/src/pages/Dashboard/index.css +0 -35
  99. jettask/webui/frontend/src/pages/Dashboard/index.jsx +0 -281
  100. jettask/webui/frontend/src/pages/Dashboard.jsx +0 -1330
  101. jettask/webui/frontend/src/pages/QueueDetail.jsx +0 -1117
  102. jettask/webui/frontend/src/pages/QueueMonitor.jsx +0 -527
  103. jettask/webui/frontend/src/pages/Queues.jsx +0 -12
  104. jettask/webui/frontend/src/pages/ScheduledTasks.jsx +0 -810
  105. jettask/webui/frontend/src/pages/Settings.jsx +0 -801
  106. jettask/webui/frontend/src/pages/Workers.jsx +0 -12
  107. jettask/webui/frontend/src/services/api.js +0 -159
  108. jettask/webui/frontend/src/services/queueTrend.js +0 -166
  109. jettask/webui/frontend/src/utils/suppressWarnings.js +0 -22
  110. jettask/webui/frontend/src/utils/userPreferences.js +0 -154
  111. jettask/webui/frontend/vite.config.js +0 -26
  112. jettask/webui/sql/init_database.sql +0 -640
  113. jettask-0.2.14.dist-info/RECORD +0 -172
  114. /jettask/{webui/backend → backend}/__init__.py +0 -0
  115. /jettask/{webui/backend → backend}/api/__init__.py +0 -0
  116. /jettask/{webui/backend → backend}/api/v1/__init__.py +0 -0
  117. /jettask/{webui/backend → backend}/api/v1/monitoring.py +0 -0
  118. /jettask/{webui/backend → backend}/api/v1/namespaces.py +0 -0
  119. /jettask/{webui/backend → backend}/api/v1/queues.py +0 -0
  120. /jettask/{webui/backend → backend}/api/v1/tasks.py +0 -0
  121. /jettask/{webui/backend → backend}/config.py +0 -0
  122. /jettask/{webui/backend → backend}/core/__init__.py +0 -0
  123. /jettask/{webui/backend → backend}/core/cache.py +0 -0
  124. /jettask/{webui/backend → backend}/core/database.py +0 -0
  125. /jettask/{webui/backend → backend}/core/exceptions.py +0 -0
  126. /jettask/{webui/backend → backend}/data_access.py +0 -0
  127. /jettask/{webui/backend → backend}/dependencies.py +0 -0
  128. /jettask/{webui/backend → backend}/init_meta_db.py +0 -0
  129. /jettask/{webui/backend → backend}/main_v2.py +0 -0
  130. /jettask/{webui/backend → backend}/models/__init__.py +0 -0
  131. /jettask/{webui/backend → backend}/models/requests.py +0 -0
  132. /jettask/{webui/backend → backend}/models/responses.py +0 -0
  133. /jettask/{webui/backend → backend}/queue_stats_v2.py +0 -0
  134. /jettask/{webui/backend → backend}/services/__init__.py +0 -0
  135. /jettask/{webui/backend → backend}/start.py +0 -0
  136. /jettask/{webui/cleanup_deprecated_tables.sql → cleanup_deprecated_tables.sql} +0 -0
  137. /jettask/{webui/gradio_app.py → gradio_app.py} +0 -0
  138. /jettask/{webui/__init__.py → main.py} +0 -0
  139. /jettask/{webui/models.py → models.py} +0 -0
  140. /jettask/{webui/run_monitor.py → run_monitor.py} +0 -0
  141. /jettask/{webui/schema.sql → schema.sql} +0 -0
  142. /jettask/{webui/unified_consumer_manager.py → unified_consumer_manager.py} +0 -0
  143. /jettask/{webui/models → webui_models}/__init__.py +0 -0
  144. /jettask/{webui/models → webui_models}/namespace.py +0 -0
  145. /jettask/{webui/sql → webui_sql}/batch_upsert_functions.sql +0 -0
  146. {jettask-0.2.14.dist-info → jettask-0.2.16.dist-info}/WHEEL +0 -0
  147. {jettask-0.2.14.dist-info → jettask-0.2.16.dist-info}/licenses/LICENSE +0 -0
  148. {jettask-0.2.14.dist-info → jettask-0.2.16.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,151 @@
1
+ """
2
+ Redis监控服务层
3
+ 处理Redis监控相关的业务逻辑
4
+ """
5
+ from typing import Optional, Dict, Any
6
+ import logging
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class RedisMonitorService:
12
+ """Redis监控服务类"""
13
+
14
+ def __init__(self, namespace_data_access):
15
+ """
16
+ 初始化Redis监控服务
17
+
18
+ Args:
19
+ namespace_data_access: 命名空间数据访问实例
20
+ """
21
+ self.namespace_data_access = namespace_data_access
22
+
23
+ async def get_redis_monitor_data(
24
+ self,
25
+ namespace: str
26
+ ) -> Dict[str, Any]:
27
+ """
28
+ 获取Redis监控数据
29
+
30
+ Args:
31
+ namespace: 命名空间
32
+
33
+ Returns:
34
+ Redis监控数据
35
+ """
36
+ # TODO: 实现获取Redis监控数据逻辑
37
+ return {
38
+ "namespace": namespace,
39
+ "status": "healthy",
40
+ "metrics": {}
41
+ }
42
+
43
+ async def get_redis_config(
44
+ self,
45
+ namespace: str
46
+ ) -> Dict[str, Any]:
47
+ """
48
+ 获取Redis配置信息
49
+
50
+ Args:
51
+ namespace: 命名空间
52
+
53
+ Returns:
54
+ Redis配置信息
55
+ """
56
+ # TODO: 实现获取Redis配置逻辑
57
+ return {
58
+ "namespace": namespace,
59
+ "config": {}
60
+ }
61
+
62
+ async def execute_redis_command(
63
+ self,
64
+ namespace: str,
65
+ command: str,
66
+ args: Optional[list] = None
67
+ ) -> Any:
68
+ """
69
+ 执行Redis命令
70
+
71
+ Args:
72
+ namespace: 命名空间
73
+ command: Redis命令
74
+ args: 命令参数
75
+
76
+ Returns:
77
+ 命令执行结果
78
+ """
79
+ # TODO: 实现执行Redis命令逻辑
80
+ return {
81
+ "success": True,
82
+ "result": None
83
+ }
84
+
85
+ async def get_slow_log(
86
+ self,
87
+ namespace: str,
88
+ limit: int = 10
89
+ ) -> Dict[str, Any]:
90
+ """
91
+ 获取Redis慢查询日志
92
+
93
+ Args:
94
+ namespace: 命名空间
95
+ limit: 返回记录数
96
+
97
+ Returns:
98
+ 慢查询日志数据
99
+ """
100
+ logger.info(f"获取Redis慢查询日志 - namespace: {namespace}, limit: {limit}")
101
+ # TODO: 实现获取Redis慢查询日志逻辑
102
+ return {
103
+ "namespace": namespace,
104
+ "slow_queries": [],
105
+ "total": 0
106
+ }
107
+
108
+ async def get_command_stats(
109
+ self,
110
+ namespace: str
111
+ ) -> Dict[str, Any]:
112
+ """
113
+ 获取Redis命令统计
114
+
115
+ Args:
116
+ namespace: 命名空间
117
+
118
+ Returns:
119
+ 命令统计数据
120
+ """
121
+ logger.info(f"获取Redis命令统计 - namespace: {namespace}")
122
+ # TODO: 实现获取Redis命令统计逻辑
123
+ return {
124
+ "namespace": namespace,
125
+ "command_stats": {},
126
+ "total_calls": 0
127
+ }
128
+
129
+ async def get_stream_stats(
130
+ self,
131
+ namespace: str,
132
+ stream_name: Optional[str] = None
133
+ ) -> Dict[str, Any]:
134
+ """
135
+ 获取Redis Stream统计
136
+
137
+ Args:
138
+ namespace: 命名空间
139
+ stream_name: Stream名称(可选)
140
+
141
+ Returns:
142
+ Stream统计数据
143
+ """
144
+ logger.info(f"获取Redis Stream统计 - namespace: {namespace}, stream: {stream_name}")
145
+ # TODO: 实现获取Redis Stream统计逻辑
146
+ return {
147
+ "namespace": namespace,
148
+ "stream_name": stream_name,
149
+ "streams": [],
150
+ "total_messages": 0
151
+ }
@@ -0,0 +1,207 @@
1
+ """
2
+ 定时任务服务层
3
+ 处理定时任务相关的业务逻辑
4
+ """
5
+ from typing import Optional, List, Dict, Any
6
+ import logging
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class ScheduledTaskService:
12
+ """定时任务服务类"""
13
+
14
+ def __init__(self, data_access):
15
+ """
16
+ 初始化定时任务服务
17
+
18
+ Args:
19
+ data_access: 数据访问层实例
20
+ """
21
+ self.data_access = data_access
22
+
23
+ @staticmethod
24
+ def validate_schedule_config(schedule_type: str, schedule_config: dict):
25
+ """
26
+ 验证调度配置
27
+
28
+ Args:
29
+ schedule_type: 调度类型
30
+ schedule_config: 调度配置
31
+
32
+ Raises:
33
+ ValueError: 配置无效时
34
+ """
35
+ if schedule_type == 'interval':
36
+ if 'seconds' in schedule_config:
37
+ seconds = schedule_config.get('seconds')
38
+ if seconds is None or seconds <= 0:
39
+ raise ValueError(f"间隔时间必须大于0秒,当前值: {seconds}")
40
+ if seconds < 1:
41
+ raise ValueError(
42
+ f"间隔时间不能小于1秒,当前值: {seconds}秒。"
43
+ f"小于1秒的高频任务可能影响系统性能"
44
+ )
45
+ elif 'minutes' in schedule_config:
46
+ minutes = schedule_config.get('minutes')
47
+ if minutes is None or minutes <= 0:
48
+ raise ValueError(f"间隔时间必须大于0分钟,当前值: {minutes}")
49
+ else:
50
+ raise ValueError("interval类型的任务必须指定seconds或minutes")
51
+ elif schedule_type == 'cron':
52
+ if 'cron_expression' not in schedule_config:
53
+ raise ValueError("cron类型的任务必须指定cron_expression")
54
+
55
+ async def get_scheduled_tasks(
56
+ self,
57
+ page: int = 1,
58
+ page_size: int = 20,
59
+ search: Optional[str] = None,
60
+ is_active: Optional[bool] = None,
61
+ filters: Optional[List[Dict]] = None,
62
+ time_range: Optional[str] = None,
63
+ start_time: Optional[str] = None,
64
+ end_time: Optional[str] = None
65
+ ) -> Dict[str, Any]:
66
+ """
67
+ 获取定时任务列表
68
+
69
+ Args:
70
+ page: 页码
71
+ page_size: 每页大小
72
+ search: 搜索关键字
73
+ is_active: 是否激活
74
+ filters: 筛选条件
75
+ time_range: 时间范围
76
+ start_time: 开始时间
77
+ end_time: 结束时间
78
+
79
+ Returns:
80
+ 任务列表和总数
81
+ """
82
+ async with self.data_access.get_session() as session:
83
+ tasks, total = await self.data_access.fetch_scheduled_tasks(
84
+ session=session,
85
+ page=page,
86
+ page_size=page_size,
87
+ search=search,
88
+ is_active=is_active,
89
+ filters=filters,
90
+ time_range=time_range,
91
+ start_time=start_time,
92
+ end_time=end_time
93
+ )
94
+
95
+ return {
96
+ "success": True,
97
+ "data": tasks,
98
+ "total": total,
99
+ "page": page,
100
+ "page_size": page_size
101
+ }
102
+
103
+ async def create_scheduled_task(
104
+ self,
105
+ task_data: Dict[str, Any]
106
+ ) -> Dict[str, Any]:
107
+ """
108
+ 创建定时任务
109
+
110
+ Args:
111
+ task_data: 任务数据
112
+
113
+ Returns:
114
+ 创建的任务信息
115
+ """
116
+ # 验证调度配置
117
+ self.validate_schedule_config(
118
+ task_data['schedule_type'],
119
+ task_data['schedule_config']
120
+ )
121
+
122
+ async with self.data_access.get_session() as session:
123
+ task = await self.data_access.create_scheduled_task(session, task_data)
124
+
125
+ return {
126
+ "success": True,
127
+ "data": task,
128
+ "message": "定时任务创建成功"
129
+ }
130
+
131
+ async def update_scheduled_task(
132
+ self,
133
+ task_id: str,
134
+ task_data: Dict[str, Any]
135
+ ) -> Dict[str, Any]:
136
+ """
137
+ 更新定时任务
138
+
139
+ Args:
140
+ task_id: 任务ID
141
+ task_data: 任务数据
142
+
143
+ Returns:
144
+ 更新后的任务信息
145
+ """
146
+ # 验证调度配置
147
+ self.validate_schedule_config(
148
+ task_data['schedule_type'],
149
+ task_data['schedule_config']
150
+ )
151
+
152
+ async with self.data_access.get_session() as session:
153
+ task = await self.data_access.update_scheduled_task(
154
+ session, task_id, task_data
155
+ )
156
+
157
+ return {
158
+ "success": True,
159
+ "data": task,
160
+ "message": "定时任务更新成功"
161
+ }
162
+
163
+ async def delete_scheduled_task(self, task_id: str) -> Dict[str, Any]:
164
+ """
165
+ 删除定时任务
166
+
167
+ Args:
168
+ task_id: 任务ID
169
+
170
+ Returns:
171
+ 操作结果
172
+ """
173
+ async with self.data_access.get_session() as session:
174
+ success = await self.data_access.delete_scheduled_task(session, task_id)
175
+
176
+ if success:
177
+ return {
178
+ "success": True,
179
+ "message": f"定时任务 {task_id} 已删除"
180
+ }
181
+ else:
182
+ raise ValueError("定时任务不存在")
183
+
184
+ async def toggle_scheduled_task(self, task_id: str) -> Dict[str, Any]:
185
+ """
186
+ 启用/禁用定时任务
187
+
188
+ Args:
189
+ task_id: 任务ID
190
+
191
+ Returns:
192
+ 更新后的状态
193
+ """
194
+ async with self.data_access.get_session() as session:
195
+ task = await self.data_access.toggle_scheduled_task(session, task_id)
196
+
197
+ if task:
198
+ return {
199
+ "success": True,
200
+ "data": {
201
+ "id": task["id"],
202
+ "is_active": task["enabled"]
203
+ },
204
+ "message": "定时任务状态已更新"
205
+ }
206
+ else:
207
+ raise ValueError("定时任务不存在")