jettask 0.2.1__py3-none-any.whl → 0.2.4__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/constants.py +213 -0
- jettask/core/app.py +525 -205
- jettask/core/cli.py +193 -185
- jettask/core/consumer_manager.py +126 -34
- jettask/core/context.py +3 -0
- jettask/core/enums.py +137 -0
- jettask/core/event_pool.py +501 -168
- jettask/core/message.py +147 -0
- jettask/core/offline_worker_recovery.py +181 -114
- jettask/core/task.py +10 -174
- jettask/core/task_batch.py +153 -0
- jettask/core/unified_manager_base.py +243 -0
- jettask/core/worker_scanner.py +54 -54
- jettask/executors/asyncio.py +184 -64
- jettask/webui/backend/config.py +51 -0
- jettask/webui/backend/data_access.py +2083 -92
- jettask/webui/backend/data_api.py +3294 -0
- jettask/webui/backend/dependencies.py +261 -0
- jettask/webui/backend/init_meta_db.py +158 -0
- jettask/webui/backend/main.py +1358 -69
- jettask/webui/backend/main_unified.py +78 -0
- jettask/webui/backend/main_v2.py +394 -0
- jettask/webui/backend/namespace_api.py +295 -0
- jettask/webui/backend/namespace_api_old.py +294 -0
- jettask/webui/backend/namespace_data_access.py +611 -0
- jettask/webui/backend/queue_backlog_api.py +727 -0
- jettask/webui/backend/queue_stats_v2.py +521 -0
- jettask/webui/backend/redis_monitor_api.py +476 -0
- jettask/webui/backend/unified_api_router.py +1601 -0
- jettask/webui/db_init.py +204 -32
- jettask/webui/frontend/package-lock.json +492 -1
- jettask/webui/frontend/package.json +4 -1
- jettask/webui/frontend/src/App.css +105 -7
- jettask/webui/frontend/src/App.jsx +49 -20
- jettask/webui/frontend/src/components/NamespaceSelector.jsx +166 -0
- jettask/webui/frontend/src/components/QueueBacklogChart.jsx +298 -0
- jettask/webui/frontend/src/components/QueueBacklogTrend.jsx +638 -0
- jettask/webui/frontend/src/components/QueueDetailsTable.css +65 -0
- jettask/webui/frontend/src/components/QueueDetailsTable.jsx +487 -0
- jettask/webui/frontend/src/components/QueueDetailsTableV2.jsx +465 -0
- jettask/webui/frontend/src/components/ScheduledTaskFilter.jsx +423 -0
- jettask/webui/frontend/src/components/TaskFilter.jsx +425 -0
- jettask/webui/frontend/src/components/TimeRangeSelector.css +21 -0
- jettask/webui/frontend/src/components/TimeRangeSelector.jsx +160 -0
- jettask/webui/frontend/src/components/layout/AppLayout.css +95 -0
- jettask/webui/frontend/src/components/layout/AppLayout.jsx +49 -0
- jettask/webui/frontend/src/components/layout/Header.css +34 -10
- jettask/webui/frontend/src/components/layout/Header.jsx +31 -23
- jettask/webui/frontend/src/components/layout/SideMenu.css +137 -0
- jettask/webui/frontend/src/components/layout/SideMenu.jsx +209 -0
- jettask/webui/frontend/src/components/layout/TabsNav.css +244 -0
- jettask/webui/frontend/src/components/layout/TabsNav.jsx +206 -0
- jettask/webui/frontend/src/components/layout/UserInfo.css +197 -0
- jettask/webui/frontend/src/components/layout/UserInfo.jsx +197 -0
- jettask/webui/frontend/src/contexts/NamespaceContext.jsx +72 -0
- jettask/webui/frontend/src/contexts/TabsContext.backup.jsx +245 -0
- jettask/webui/frontend/src/main.jsx +1 -0
- jettask/webui/frontend/src/pages/Alerts.jsx +684 -0
- jettask/webui/frontend/src/pages/Dashboard.jsx +1330 -0
- jettask/webui/frontend/src/pages/QueueDetail.jsx +1109 -10
- jettask/webui/frontend/src/pages/QueueMonitor.jsx +236 -115
- jettask/webui/frontend/src/pages/Queues.jsx +5 -1
- jettask/webui/frontend/src/pages/ScheduledTasks.jsx +809 -0
- jettask/webui/frontend/src/pages/Settings.jsx +800 -0
- jettask/webui/frontend/src/services/api.js +7 -5
- jettask/webui/frontend/src/utils/suppressWarnings.js +22 -0
- jettask/webui/frontend/src/utils/userPreferences.js +154 -0
- jettask/webui/multi_namespace_consumer.py +543 -0
- jettask/webui/pg_consumer.py +983 -246
- jettask/webui/static/dist/assets/index-7129cfe1.css +1 -0
- jettask/webui/static/dist/assets/index-8d1935cc.js +774 -0
- jettask/webui/static/dist/index.html +2 -2
- jettask/webui/task_center.py +216 -0
- jettask/webui/task_center_client.py +150 -0
- jettask/webui/unified_consumer_manager.py +193 -0
- {jettask-0.2.1.dist-info → jettask-0.2.4.dist-info}/METADATA +1 -1
- jettask-0.2.4.dist-info/RECORD +134 -0
- jettask/webui/pg_consumer_slow.py +0 -1099
- jettask/webui/pg_consumer_test.py +0 -678
- jettask/webui/static/dist/assets/index-823408e8.css +0 -1
- jettask/webui/static/dist/assets/index-9968b0b8.js +0 -543
- jettask/webui/test_pg_consumer_recovery.py +0 -547
- jettask/webui/test_recovery_simple.py +0 -492
- jettask/webui/test_self_recovery.py +0 -467
- jettask-0.2.1.dist-info/RECORD +0 -91
- {jettask-0.2.1.dist-info → jettask-0.2.4.dist-info}/WHEEL +0 -0
- {jettask-0.2.1.dist-info → jettask-0.2.4.dist-info}/entry_points.txt +0 -0
- {jettask-0.2.1.dist-info → jettask-0.2.4.dist-info}/licenses/LICENSE +0 -0
- {jettask-0.2.1.dist-info → jettask-0.2.4.dist-info}/top_level.txt +0 -0
jettask/constants.py
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
"""
|
2
|
+
JetTask 系统常量定义
|
3
|
+
|
4
|
+
集中管理所有系统级别的常量配置,包括:
|
5
|
+
- 内部消费者组
|
6
|
+
- 系统保留关键字
|
7
|
+
- 默认配置值
|
8
|
+
- 其他常量
|
9
|
+
"""
|
10
|
+
|
11
|
+
# ============================================================================
|
12
|
+
# 内部消费者组配置
|
13
|
+
# ============================================================================
|
14
|
+
|
15
|
+
# 内部消费者组前缀列表
|
16
|
+
# 任何以这些前缀开头的消费者组都会被视为内部消费者组,不会在用户界面显示
|
17
|
+
INTERNAL_CONSUMER_PREFIXES = [
|
18
|
+
'pg_consumer_', # PostgreSQL 消费者
|
19
|
+
'webui_consumer_', # WebUI 消费者
|
20
|
+
'monitor_', # 监控消费者
|
21
|
+
'system_', # 系统消费者
|
22
|
+
'_internal_', # 通用内部消费者
|
23
|
+
'__', # 双下划线开头的保留消费者
|
24
|
+
]
|
25
|
+
|
26
|
+
# 特定的内部消费者组名称(完全匹配)
|
27
|
+
INTERNAL_CONSUMER_NAMES = [
|
28
|
+
'pg_consumer', # 默认的 PostgreSQL 消费者
|
29
|
+
'webui_consumer', # 默认的 WebUI 消费者
|
30
|
+
'system', # 系统消费者
|
31
|
+
]
|
32
|
+
|
33
|
+
# ============================================================================
|
34
|
+
# Redis 键前缀和模式
|
35
|
+
# ============================================================================
|
36
|
+
|
37
|
+
# Redis 键前缀
|
38
|
+
REDIS_KEY_PREFIX = {
|
39
|
+
'QUEUE': 'QUEUE', # 队列前缀
|
40
|
+
'TASK': 'TASK', # 任务前缀
|
41
|
+
'WORKER': 'WORKER', # Worker前缀
|
42
|
+
'LEADER': 'leader', # Leader锁前缀
|
43
|
+
'QUEUE_OFFSETS': 'QUEUE_OFFSETS', # 队列偏移量
|
44
|
+
'TASK_OFFSETS': 'TASK_OFFSETS', # 任务偏移量
|
45
|
+
'SCHEDULED': 'scheduled', # 定时任务前缀
|
46
|
+
'MONITOR': 'monitor', # 监控前缀
|
47
|
+
}
|
48
|
+
|
49
|
+
# ============================================================================
|
50
|
+
# 数据库相关常量
|
51
|
+
# ============================================================================
|
52
|
+
|
53
|
+
# 分区表配置
|
54
|
+
PARTITION_TABLE_CONFIG = {
|
55
|
+
'tasks': {
|
56
|
+
'partition_by': 'created_at',
|
57
|
+
'interval': 'daily', # daily, weekly, monthly
|
58
|
+
'retention_days': 30, # 保留天数
|
59
|
+
},
|
60
|
+
'task_runs': {
|
61
|
+
'partition_by': 'created_at',
|
62
|
+
'interval': 'daily',
|
63
|
+
'retention_days': 30,
|
64
|
+
},
|
65
|
+
'stream_backlog_monitor': {
|
66
|
+
'partition_by': 'created_at',
|
67
|
+
'interval': 'hourly', # 小时级分区
|
68
|
+
'retention_days': 7, # 保留7天
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
# ============================================================================
|
73
|
+
# 系统默认值
|
74
|
+
# ============================================================================
|
75
|
+
|
76
|
+
# 默认超时设置(秒)
|
77
|
+
DEFAULT_TIMEOUTS = {
|
78
|
+
'task_execution': 300, # 任务执行超时(5分钟)
|
79
|
+
'task_ack': 60, # 任务确认超时(1分钟)
|
80
|
+
'worker_heartbeat': 30, # Worker心跳超时(30秒)
|
81
|
+
'lock_ttl': 60, # 分布式锁TTL(60秒)
|
82
|
+
'redis_operation': 5, # Redis操作超时(5秒)
|
83
|
+
}
|
84
|
+
|
85
|
+
# 默认限制值
|
86
|
+
DEFAULT_LIMITS = {
|
87
|
+
'max_retries': 3, # 最大重试次数
|
88
|
+
'max_pending_per_group': 1000, # 每个消费组最大pending数
|
89
|
+
'max_batch_size': 100, # 最大批处理大小
|
90
|
+
'max_prefetch': 100, # 最大预取数量
|
91
|
+
}
|
92
|
+
|
93
|
+
# 监控和统计间隔(秒)
|
94
|
+
MONITOR_INTERVALS = {
|
95
|
+
'backlog_monitor': 1, # 积压监控间隔
|
96
|
+
'health_check': 30, # 健康检查间隔
|
97
|
+
'namespace_check': 60, # 命名空间检查间隔(默认)
|
98
|
+
'stats_aggregation': 60, # 统计聚合间隔
|
99
|
+
}
|
100
|
+
|
101
|
+
# ============================================================================
|
102
|
+
# 任务状态定义
|
103
|
+
# ============================================================================
|
104
|
+
|
105
|
+
# 任务状态优先级(数值越大,状态越"新")
|
106
|
+
TASK_STATUS_PRIORITY = {
|
107
|
+
'pending': 1, # 待处理
|
108
|
+
'running': 2, # 运行中
|
109
|
+
'success': 3, # 成功(终态)
|
110
|
+
'error': 3, # 错误(终态)
|
111
|
+
'failed': 3, # 失败(终态)
|
112
|
+
'timeout': 3, # 超时(终态)
|
113
|
+
'rejected': 3, # 拒绝(终态)
|
114
|
+
'cancelled': 3, # 取消(终态)
|
115
|
+
}
|
116
|
+
|
117
|
+
# 终态状态列表
|
118
|
+
TASK_FINAL_STATES = ['success', 'error', 'failed', 'timeout', 'rejected', 'cancelled']
|
119
|
+
|
120
|
+
# 可重试状态列表
|
121
|
+
TASK_RETRYABLE_STATES = ['error', 'failed', 'timeout']
|
122
|
+
|
123
|
+
# ============================================================================
|
124
|
+
# 辅助函数
|
125
|
+
# ============================================================================
|
126
|
+
|
127
|
+
def is_internal_consumer(consumer_group: str) -> bool:
|
128
|
+
"""
|
129
|
+
判断给定的消费者组是否为内部消费者组
|
130
|
+
|
131
|
+
Args:
|
132
|
+
consumer_group: 消费者组名称
|
133
|
+
|
134
|
+
Returns:
|
135
|
+
如果是内部消费者组返回 True,否则返回 False
|
136
|
+
"""
|
137
|
+
if not consumer_group:
|
138
|
+
return False
|
139
|
+
|
140
|
+
# 转换为小写进行比较
|
141
|
+
consumer_group_lower = consumer_group.lower()
|
142
|
+
|
143
|
+
# 检查完全匹配(不区分大小写)
|
144
|
+
for name in INTERNAL_CONSUMER_NAMES:
|
145
|
+
if consumer_group_lower == name.lower():
|
146
|
+
return True
|
147
|
+
|
148
|
+
# 检查前缀匹配(不区分大小写)
|
149
|
+
for prefix in INTERNAL_CONSUMER_PREFIXES:
|
150
|
+
if consumer_group_lower.startswith(prefix.lower()):
|
151
|
+
return True
|
152
|
+
|
153
|
+
# 特殊处理:模糊匹配包含特定关键字的消费者组
|
154
|
+
# 例如:pg_consumer 可能以不同格式出现,如 pg_consumer_YYDG_12345
|
155
|
+
internal_keywords = [
|
156
|
+
'pg_consumer', # PostgreSQL 消费者的各种变体
|
157
|
+
'webui_consumer', # WebUI 消费者的各种变体
|
158
|
+
]
|
159
|
+
|
160
|
+
for keyword in internal_keywords:
|
161
|
+
if keyword in consumer_group_lower:
|
162
|
+
return True
|
163
|
+
|
164
|
+
return False
|
165
|
+
|
166
|
+
|
167
|
+
def filter_internal_consumers(consumer_groups: list) -> list:
|
168
|
+
"""
|
169
|
+
从消费者组列表中过滤掉内部消费者组
|
170
|
+
|
171
|
+
Args:
|
172
|
+
consumer_groups: 消费者组名称列表
|
173
|
+
|
174
|
+
Returns:
|
175
|
+
过滤后的消费者组列表
|
176
|
+
"""
|
177
|
+
return [cg for cg in consumer_groups if not is_internal_consumer(cg)]
|
178
|
+
|
179
|
+
|
180
|
+
def get_redis_key(namespace: str, key_type: str, *parts) -> str:
|
181
|
+
"""
|
182
|
+
构建Redis键
|
183
|
+
|
184
|
+
Args:
|
185
|
+
namespace: 命名空间
|
186
|
+
key_type: 键类型(从REDIS_KEY_PREFIX中选择)
|
187
|
+
*parts: 其他键组成部分
|
188
|
+
|
189
|
+
Returns:
|
190
|
+
完整的Redis键
|
191
|
+
"""
|
192
|
+
prefix = REDIS_KEY_PREFIX.get(key_type, key_type)
|
193
|
+
key_parts = [namespace, prefix] + list(parts)
|
194
|
+
return ':'.join(str(p) for p in key_parts if p)
|
195
|
+
|
196
|
+
|
197
|
+
def get_partition_interval_seconds(interval: str) -> int:
|
198
|
+
"""
|
199
|
+
获取分区间隔对应的秒数
|
200
|
+
|
201
|
+
Args:
|
202
|
+
interval: 分区间隔(hourly, daily, weekly, monthly)
|
203
|
+
|
204
|
+
Returns:
|
205
|
+
对应的秒数
|
206
|
+
"""
|
207
|
+
intervals = {
|
208
|
+
'hourly': 3600,
|
209
|
+
'daily': 86400,
|
210
|
+
'weekly': 604800,
|
211
|
+
'monthly': 2592000, # 30天
|
212
|
+
}
|
213
|
+
return intervals.get(interval, 86400) # 默认返回一天
|