jettask 0.2.4__py3-none-any.whl → 0.2.6__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 (94) hide show
  1. jettask/core/cli.py +20 -24
  2. jettask/monitor/run_backlog_collector.py +96 -0
  3. jettask/monitor/stream_backlog_monitor.py +362 -0
  4. jettask/pg_consumer/pg_consumer_v2.py +403 -0
  5. jettask/pg_consumer/sql_utils.py +182 -0
  6. jettask/scheduler/__init__.py +17 -0
  7. jettask/scheduler/add_execution_count.sql +11 -0
  8. jettask/scheduler/add_priority_field.sql +26 -0
  9. jettask/scheduler/add_scheduler_id.sql +25 -0
  10. jettask/scheduler/add_scheduler_id_index.sql +10 -0
  11. jettask/scheduler/loader.py +249 -0
  12. jettask/scheduler/make_scheduler_id_required.sql +28 -0
  13. jettask/scheduler/manager.py +696 -0
  14. jettask/scheduler/migrate_interval_seconds.sql +9 -0
  15. jettask/scheduler/models.py +200 -0
  16. jettask/scheduler/multi_namespace_scheduler.py +294 -0
  17. jettask/scheduler/performance_optimization.sql +45 -0
  18. jettask/scheduler/run_scheduler.py +186 -0
  19. jettask/scheduler/scheduler.py +715 -0
  20. jettask/scheduler/schema.sql +84 -0
  21. jettask/scheduler/unified_manager.py +450 -0
  22. jettask/scheduler/unified_scheduler_manager.py +280 -0
  23. jettask/webui/backend/api/__init__.py +3 -0
  24. jettask/webui/backend/api/v1/__init__.py +17 -0
  25. jettask/webui/backend/api/v1/monitoring.py +431 -0
  26. jettask/webui/backend/api/v1/namespaces.py +504 -0
  27. jettask/webui/backend/api/v1/queues.py +342 -0
  28. jettask/webui/backend/api/v1/tasks.py +367 -0
  29. jettask/webui/backend/core/__init__.py +3 -0
  30. jettask/webui/backend/core/cache.py +221 -0
  31. jettask/webui/backend/core/database.py +200 -0
  32. jettask/webui/backend/core/exceptions.py +102 -0
  33. jettask/webui/backend/models/__init__.py +3 -0
  34. jettask/webui/backend/models/requests.py +236 -0
  35. jettask/webui/backend/models/responses.py +230 -0
  36. jettask/webui/backend/services/__init__.py +3 -0
  37. jettask/webui/frontend/index.html +13 -0
  38. jettask/webui/models/__init__.py +3 -0
  39. jettask/webui/models/namespace.py +63 -0
  40. jettask/webui/sql/batch_upsert_functions.sql +178 -0
  41. jettask/webui/sql/init_database.sql +640 -0
  42. {jettask-0.2.4.dist-info → jettask-0.2.6.dist-info}/METADATA +11 -9
  43. {jettask-0.2.4.dist-info → jettask-0.2.6.dist-info}/RECORD +47 -54
  44. jettask/webui/frontend/package-lock.json +0 -4833
  45. jettask/webui/frontend/package.json +0 -30
  46. jettask/webui/frontend/src/App.css +0 -109
  47. jettask/webui/frontend/src/App.jsx +0 -66
  48. jettask/webui/frontend/src/components/NamespaceSelector.jsx +0 -166
  49. jettask/webui/frontend/src/components/QueueBacklogChart.jsx +0 -298
  50. jettask/webui/frontend/src/components/QueueBacklogTrend.jsx +0 -638
  51. jettask/webui/frontend/src/components/QueueDetailsTable.css +0 -65
  52. jettask/webui/frontend/src/components/QueueDetailsTable.jsx +0 -487
  53. jettask/webui/frontend/src/components/QueueDetailsTableV2.jsx +0 -465
  54. jettask/webui/frontend/src/components/ScheduledTaskFilter.jsx +0 -423
  55. jettask/webui/frontend/src/components/TaskFilter.jsx +0 -425
  56. jettask/webui/frontend/src/components/TimeRangeSelector.css +0 -21
  57. jettask/webui/frontend/src/components/TimeRangeSelector.jsx +0 -160
  58. jettask/webui/frontend/src/components/charts/QueueChart.jsx +0 -111
  59. jettask/webui/frontend/src/components/charts/QueueTrendChart.jsx +0 -115
  60. jettask/webui/frontend/src/components/charts/WorkerChart.jsx +0 -40
  61. jettask/webui/frontend/src/components/common/StatsCard.jsx +0 -18
  62. jettask/webui/frontend/src/components/layout/AppLayout.css +0 -95
  63. jettask/webui/frontend/src/components/layout/AppLayout.jsx +0 -49
  64. jettask/webui/frontend/src/components/layout/Header.css +0 -106
  65. jettask/webui/frontend/src/components/layout/Header.jsx +0 -106
  66. jettask/webui/frontend/src/components/layout/SideMenu.css +0 -137
  67. jettask/webui/frontend/src/components/layout/SideMenu.jsx +0 -209
  68. jettask/webui/frontend/src/components/layout/TabsNav.css +0 -244
  69. jettask/webui/frontend/src/components/layout/TabsNav.jsx +0 -206
  70. jettask/webui/frontend/src/components/layout/UserInfo.css +0 -197
  71. jettask/webui/frontend/src/components/layout/UserInfo.jsx +0 -197
  72. jettask/webui/frontend/src/contexts/LoadingContext.jsx +0 -27
  73. jettask/webui/frontend/src/contexts/NamespaceContext.jsx +0 -72
  74. jettask/webui/frontend/src/contexts/TabsContext.backup.jsx +0 -245
  75. jettask/webui/frontend/src/index.css +0 -114
  76. jettask/webui/frontend/src/main.jsx +0 -20
  77. jettask/webui/frontend/src/pages/Alerts.jsx +0 -684
  78. jettask/webui/frontend/src/pages/Dashboard/index.css +0 -35
  79. jettask/webui/frontend/src/pages/Dashboard/index.jsx +0 -281
  80. jettask/webui/frontend/src/pages/Dashboard.jsx +0 -1330
  81. jettask/webui/frontend/src/pages/QueueDetail.jsx +0 -1117
  82. jettask/webui/frontend/src/pages/QueueMonitor.jsx +0 -527
  83. jettask/webui/frontend/src/pages/Queues.jsx +0 -12
  84. jettask/webui/frontend/src/pages/ScheduledTasks.jsx +0 -809
  85. jettask/webui/frontend/src/pages/Settings.jsx +0 -800
  86. jettask/webui/frontend/src/pages/Workers.jsx +0 -12
  87. jettask/webui/frontend/src/services/api.js +0 -114
  88. jettask/webui/frontend/src/services/queueTrend.js +0 -152
  89. jettask/webui/frontend/src/utils/suppressWarnings.js +0 -22
  90. jettask/webui/frontend/src/utils/userPreferences.js +0 -154
  91. {jettask-0.2.4.dist-info → jettask-0.2.6.dist-info}/WHEEL +0 -0
  92. {jettask-0.2.4.dist-info → jettask-0.2.6.dist-info}/entry_points.txt +0 -0
  93. {jettask-0.2.4.dist-info → jettask-0.2.6.dist-info}/licenses/LICENSE +0 -0
  94. {jettask-0.2.4.dist-info → jettask-0.2.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ 定时任务调度器启动脚本
4
+ """
5
+ import asyncio
6
+ import os
7
+ import sys
8
+ import signal
9
+ from pathlib import Path
10
+
11
+ # 添加项目根目录到Python路径
12
+ project_root = Path(__file__).parent.parent.parent
13
+ sys.path.insert(0, str(project_root))
14
+
15
+ from jettask import Jettask
16
+ from jettask.scheduler.scheduler import TaskScheduler
17
+ from jettask.scheduler.manager import ScheduledTaskManager
18
+ from jettask.utils.task_logger import get_task_logger
19
+
20
+ logger = get_task_logger(__name__)
21
+
22
+
23
+ class SchedulerRunner:
24
+ """调度器运行器"""
25
+
26
+ def __init__(self):
27
+ self.scheduler = None
28
+ self.app = None
29
+ self.running = False
30
+
31
+ async def setup(self):
32
+ """初始化设置"""
33
+ # 从环境变量获取配置
34
+ redis_url = os.getenv('JETTASK_REDIS_URL', 'redis://localhost:6379/0')
35
+ db_url = os.getenv('JETTASK_PG_URL', 'postgresql://jettask:123456@localhost:5432/jettask')
36
+
37
+ # 创建Jettask应用实例
38
+ self.app = Jettask(
39
+ redis_url=redis_url,
40
+ pg_url=db_url
41
+ )
42
+
43
+ # 导入任务模块(确保任务被注册)
44
+ try:
45
+ # 尝试导入用户定义的任务模块
46
+ import importlib
47
+ import importlib.util
48
+
49
+ # 先尝试加载示例模块
50
+ example_paths = [
51
+ 'examples.scheduler_auto_demo',
52
+ 'scheduler_auto_demo'
53
+ ]
54
+
55
+ for path in example_paths:
56
+ try:
57
+ example_module = importlib.import_module(path)
58
+ if hasattr(example_module, 'app'):
59
+ # 将任务模块中的任务复制到调度器的app中
60
+ for task_name, task_obj in example_module.app._tasks.items():
61
+ self.app._tasks[task_name] = task_obj
62
+ # 也注册带模块名的任务
63
+ full_name = f"scheduler_auto_demo.{task_name}"
64
+ self.app._tasks[full_name] = task_obj
65
+ logger.info(f"Registered task: {task_name} and {full_name}")
66
+ logger.info(f"Loaded example tasks from module: {path}")
67
+ break
68
+ except ImportError:
69
+ continue
70
+
71
+ # 然后加载用户指定的任务模块
72
+ task_module = os.getenv('JETTASK_TASKS_MODULE', 'tasks')
73
+ if task_module:
74
+ try:
75
+ module = importlib.import_module(task_module)
76
+ # 获取模块中的app对象的任务
77
+ if hasattr(module, 'app'):
78
+ # 将任务模块中的任务复制到调度器的app中
79
+ for task_name, task_obj in module.app._tasks.items():
80
+ self.app._tasks[task_name] = task_obj
81
+ logger.info(f"Registered task: {task_name}")
82
+
83
+ # 注册别名任务(scheduler_auto_demo.send_notification)
84
+ if hasattr(module, 'send_notification'):
85
+ self.app._tasks['scheduler_auto_demo.send_notification'] = module.send_notification
86
+ logger.info("Registered task: scheduler_auto_demo.send_notification")
87
+
88
+ logger.info(f"Loaded tasks from module: {task_module}")
89
+ except ImportError as e:
90
+ logger.warning(f"Could not import tasks module '{task_module}': {e}")
91
+ except Exception as e:
92
+ logger.warning(f"Error loading tasks: {e}")
93
+
94
+ # 创建数据库管理器
95
+ db_manager = ScheduledTaskManager(db_url)
96
+ await db_manager.connect()
97
+
98
+ # 确保数据库表存在
99
+ await db_manager.init_schema()
100
+
101
+ # 创建调度器
102
+ self.scheduler = TaskScheduler(
103
+ app=self.app,
104
+ redis_url=redis_url,
105
+ db_manager=db_manager,
106
+ redis_prefix="jettask:scheduled",
107
+ scan_interval=0.5, # 每0.5秒扫描一次
108
+ batch_size=100, # 每批处理100个任务
109
+ leader_ttl=30 # Leader锁30秒过期
110
+ )
111
+
112
+ await self.scheduler.connect()
113
+ logger.info("Scheduler setup completed")
114
+
115
+ async def run(self):
116
+ """运行调度器"""
117
+ self.running = True
118
+ logger.info("Starting scheduler...")
119
+
120
+ try:
121
+ # 运行调度器
122
+ await self.scheduler.run()
123
+ except Exception as e:
124
+ logger.error(f"Scheduler error: {e}", exc_info=True)
125
+ finally:
126
+ self.running = False
127
+ logger.info("Scheduler stopped")
128
+
129
+ async def shutdown(self):
130
+ """关闭调度器"""
131
+ logger.info("Shutting down scheduler...")
132
+
133
+ if self.scheduler:
134
+ self.scheduler.stop()
135
+ await self.scheduler.disconnect()
136
+
137
+ if self.app:
138
+ # 关闭应用连接
139
+ pass
140
+
141
+ logger.info("Scheduler shutdown completed")
142
+
143
+ def handle_signal(self, signum, frame):
144
+ """处理终止信号"""
145
+ logger.info(f"Received signal {signum}, initiating shutdown...")
146
+ self.running = False
147
+
148
+ # 创建关闭任务
149
+ if self.scheduler:
150
+ self.scheduler.stop()
151
+
152
+
153
+ async def main():
154
+ """主函数"""
155
+ runner = SchedulerRunner()
156
+
157
+ # 设置信号处理
158
+ signal.signal(signal.SIGINT, runner.handle_signal)
159
+ signal.signal(signal.SIGTERM, runner.handle_signal)
160
+
161
+ try:
162
+ # 初始化
163
+ await runner.setup()
164
+
165
+ # 运行调度器
166
+ await runner.run()
167
+
168
+ except KeyboardInterrupt:
169
+ logger.info("Received keyboard interrupt")
170
+ except Exception as e:
171
+ logger.error(f"Unexpected error: {e}", exc_info=True)
172
+ finally:
173
+ # 清理
174
+ await runner.shutdown()
175
+
176
+
177
+ if __name__ == '__main__':
178
+ # 设置日志级别
179
+ import logging
180
+ logging.basicConfig(
181
+ level=logging.INFO,
182
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
183
+ )
184
+
185
+ # 运行主函数
186
+ asyncio.run(main())