jettask 0.2.5__py3-none-any.whl → 0.2.7__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 (93) hide show
  1. jettask/monitor/run_backlog_collector.py +96 -0
  2. jettask/monitor/stream_backlog_monitor.py +362 -0
  3. jettask/pg_consumer/pg_consumer_v2.py +403 -0
  4. jettask/pg_consumer/sql_utils.py +182 -0
  5. jettask/scheduler/__init__.py +17 -0
  6. jettask/scheduler/add_execution_count.sql +11 -0
  7. jettask/scheduler/add_priority_field.sql +26 -0
  8. jettask/scheduler/add_scheduler_id.sql +25 -0
  9. jettask/scheduler/add_scheduler_id_index.sql +10 -0
  10. jettask/scheduler/loader.py +249 -0
  11. jettask/scheduler/make_scheduler_id_required.sql +28 -0
  12. jettask/scheduler/manager.py +696 -0
  13. jettask/scheduler/migrate_interval_seconds.sql +9 -0
  14. jettask/scheduler/models.py +200 -0
  15. jettask/scheduler/multi_namespace_scheduler.py +294 -0
  16. jettask/scheduler/performance_optimization.sql +45 -0
  17. jettask/scheduler/run_scheduler.py +186 -0
  18. jettask/scheduler/scheduler.py +715 -0
  19. jettask/scheduler/schema.sql +84 -0
  20. jettask/scheduler/unified_manager.py +450 -0
  21. jettask/scheduler/unified_scheduler_manager.py +280 -0
  22. jettask/webui/backend/api/__init__.py +3 -0
  23. jettask/webui/backend/api/v1/__init__.py +17 -0
  24. jettask/webui/backend/api/v1/monitoring.py +431 -0
  25. jettask/webui/backend/api/v1/namespaces.py +504 -0
  26. jettask/webui/backend/api/v1/queues.py +342 -0
  27. jettask/webui/backend/api/v1/tasks.py +367 -0
  28. jettask/webui/backend/core/__init__.py +3 -0
  29. jettask/webui/backend/core/cache.py +221 -0
  30. jettask/webui/backend/core/database.py +200 -0
  31. jettask/webui/backend/core/exceptions.py +102 -0
  32. jettask/webui/backend/models/__init__.py +3 -0
  33. jettask/webui/backend/models/requests.py +236 -0
  34. jettask/webui/backend/models/responses.py +230 -0
  35. jettask/webui/backend/services/__init__.py +3 -0
  36. jettask/webui/frontend/index.html +13 -0
  37. jettask/webui/models/__init__.py +3 -0
  38. jettask/webui/models/namespace.py +63 -0
  39. jettask/webui/sql/batch_upsert_functions.sql +178 -0
  40. jettask/webui/sql/init_database.sql +640 -0
  41. {jettask-0.2.5.dist-info → jettask-0.2.7.dist-info}/METADATA +80 -10
  42. {jettask-0.2.5.dist-info → jettask-0.2.7.dist-info}/RECORD +46 -53
  43. jettask/webui/frontend/package-lock.json +0 -4833
  44. jettask/webui/frontend/package.json +0 -30
  45. jettask/webui/frontend/src/App.css +0 -109
  46. jettask/webui/frontend/src/App.jsx +0 -66
  47. jettask/webui/frontend/src/components/NamespaceSelector.jsx +0 -166
  48. jettask/webui/frontend/src/components/QueueBacklogChart.jsx +0 -298
  49. jettask/webui/frontend/src/components/QueueBacklogTrend.jsx +0 -638
  50. jettask/webui/frontend/src/components/QueueDetailsTable.css +0 -65
  51. jettask/webui/frontend/src/components/QueueDetailsTable.jsx +0 -487
  52. jettask/webui/frontend/src/components/QueueDetailsTableV2.jsx +0 -465
  53. jettask/webui/frontend/src/components/ScheduledTaskFilter.jsx +0 -423
  54. jettask/webui/frontend/src/components/TaskFilter.jsx +0 -425
  55. jettask/webui/frontend/src/components/TimeRangeSelector.css +0 -21
  56. jettask/webui/frontend/src/components/TimeRangeSelector.jsx +0 -160
  57. jettask/webui/frontend/src/components/charts/QueueChart.jsx +0 -111
  58. jettask/webui/frontend/src/components/charts/QueueTrendChart.jsx +0 -115
  59. jettask/webui/frontend/src/components/charts/WorkerChart.jsx +0 -40
  60. jettask/webui/frontend/src/components/common/StatsCard.jsx +0 -18
  61. jettask/webui/frontend/src/components/layout/AppLayout.css +0 -95
  62. jettask/webui/frontend/src/components/layout/AppLayout.jsx +0 -49
  63. jettask/webui/frontend/src/components/layout/Header.css +0 -106
  64. jettask/webui/frontend/src/components/layout/Header.jsx +0 -106
  65. jettask/webui/frontend/src/components/layout/SideMenu.css +0 -137
  66. jettask/webui/frontend/src/components/layout/SideMenu.jsx +0 -209
  67. jettask/webui/frontend/src/components/layout/TabsNav.css +0 -244
  68. jettask/webui/frontend/src/components/layout/TabsNav.jsx +0 -206
  69. jettask/webui/frontend/src/components/layout/UserInfo.css +0 -197
  70. jettask/webui/frontend/src/components/layout/UserInfo.jsx +0 -197
  71. jettask/webui/frontend/src/contexts/LoadingContext.jsx +0 -27
  72. jettask/webui/frontend/src/contexts/NamespaceContext.jsx +0 -72
  73. jettask/webui/frontend/src/contexts/TabsContext.backup.jsx +0 -245
  74. jettask/webui/frontend/src/index.css +0 -114
  75. jettask/webui/frontend/src/main.jsx +0 -20
  76. jettask/webui/frontend/src/pages/Alerts.jsx +0 -684
  77. jettask/webui/frontend/src/pages/Dashboard/index.css +0 -35
  78. jettask/webui/frontend/src/pages/Dashboard/index.jsx +0 -281
  79. jettask/webui/frontend/src/pages/Dashboard.jsx +0 -1330
  80. jettask/webui/frontend/src/pages/QueueDetail.jsx +0 -1117
  81. jettask/webui/frontend/src/pages/QueueMonitor.jsx +0 -527
  82. jettask/webui/frontend/src/pages/Queues.jsx +0 -12
  83. jettask/webui/frontend/src/pages/ScheduledTasks.jsx +0 -809
  84. jettask/webui/frontend/src/pages/Settings.jsx +0 -800
  85. jettask/webui/frontend/src/pages/Workers.jsx +0 -12
  86. jettask/webui/frontend/src/services/api.js +0 -114
  87. jettask/webui/frontend/src/services/queueTrend.js +0 -152
  88. jettask/webui/frontend/src/utils/suppressWarnings.js +0 -22
  89. jettask/webui/frontend/src/utils/userPreferences.js +0 -154
  90. {jettask-0.2.5.dist-info → jettask-0.2.7.dist-info}/WHEEL +0 -0
  91. {jettask-0.2.5.dist-info → jettask-0.2.7.dist-info}/entry_points.txt +0 -0
  92. {jettask-0.2.5.dist-info → jettask-0.2.7.dist-info}/licenses/LICENSE +0 -0
  93. {jettask-0.2.5.dist-info → jettask-0.2.7.dist-info}/top_level.txt +0 -0
@@ -1,137 +0,0 @@
1
- /* 侧边栏样式 */
2
- .app-sider {
3
- position: fixed;
4
- left: 0;
5
- top: 0;
6
- bottom: 0;
7
- z-index: 100;
8
- box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
9
- }
10
-
11
- /* Logo区域 */
12
- .sider-header {
13
- height: 48px;
14
- display: flex;
15
- align-items: center;
16
- justify-content: center;
17
- border-bottom: 1px solid #303030;
18
- }
19
-
20
- .logo-container {
21
- display: flex;
22
- align-items: center;
23
- justify-content: center;
24
- }
25
-
26
- .logo-icon {
27
- color: #1890ff;
28
- font-size: 20px;
29
- font-weight: bold;
30
- width: 28px;
31
- height: 28px;
32
- display: flex;
33
- align-items: center;
34
- justify-content: center;
35
- background: rgba(24, 144, 255, 0.1);
36
- border-radius: 4px;
37
- }
38
-
39
- /* 菜单样式 */
40
- .side-menu {
41
- padding: 12px 0;
42
- }
43
-
44
- /* 紧凑菜单样式 */
45
- .side-menu.compact .ant-menu-item {
46
- height: 56px;
47
- line-height: 56px;
48
- margin: 0 0 8px 0 !important;
49
- padding: 0 !important;
50
- display: flex;
51
- flex-direction: column;
52
- align-items: center;
53
- justify-content: center;
54
- color: rgba(255, 255, 255, 0.65);
55
- transition: all 0.2s;
56
- }
57
-
58
- .side-menu.compact .ant-menu-item:hover {
59
- color: #fff !important;
60
- background: rgba(24, 144, 255, 0.1) !important;
61
- }
62
-
63
- .side-menu.compact .ant-menu-item-selected {
64
- background: transparent !important;
65
- color: #1890ff !important;
66
- position: relative;
67
- }
68
-
69
- .side-menu.compact .ant-menu-item-selected::before {
70
- content: '';
71
- position: absolute;
72
- left: 0;
73
- top: 50%;
74
- transform: translateY(-50%);
75
- width: 3px;
76
- height: 24px;
77
- background: #1890ff;
78
- border-radius: 0 2px 2px 0;
79
- }
80
-
81
- .side-menu.compact .ant-menu-item-selected::after {
82
- display: none;
83
- }
84
-
85
- /* 菜单项内容容器 */
86
- .menu-item-content {
87
- display: flex;
88
- flex-direction: column;
89
- align-items: center;
90
- justify-content: center;
91
- width: 100%;
92
- height: 100%;
93
- }
94
-
95
- /* 图标包装器 */
96
- .menu-icon-wrapper {
97
- display: flex;
98
- align-items: center;
99
- justify-content: center;
100
- font-size: 18px;
101
- margin-bottom: 6px;
102
- }
103
-
104
- /* 菜单标签 */
105
- .menu-label {
106
- font-size: 11px;
107
- line-height: 1;
108
- white-space: nowrap;
109
- opacity: 0.85;
110
- font-weight: 400;
111
- }
112
-
113
- /* 图标和文字垂直排列 */
114
- .side-menu.compact .ant-menu-item .ant-menu-item-icon {
115
- margin: 0;
116
- min-width: auto;
117
- }
118
-
119
- .side-menu.compact .ant-menu-title-content {
120
- margin: 0;
121
- padding: 0;
122
- }
123
-
124
- /* 分割线样式 */
125
- .ant-menu-item-divider {
126
- margin: 12px 8px;
127
- border-color: #303030;
128
- }
129
-
130
- /* 移除默认的内边距 */
131
- .side-menu.compact .ant-menu-inline {
132
- border: none;
133
- }
134
-
135
- .side-menu.compact .ant-menu-sub {
136
- background: transparent !important;
137
- }
@@ -1,209 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { Layout, Menu, Tooltip } from 'antd';
3
- import { useNavigate, useLocation } from 'react-router-dom';
4
- import {
5
- DashboardOutlined,
6
- AppstoreOutlined,
7
- ClockCircleOutlined,
8
- AlertOutlined,
9
- SettingOutlined,
10
- DatabaseOutlined,
11
- BarChartOutlined,
12
- TeamOutlined,
13
- CloudServerOutlined,
14
- MenuFoldOutlined,
15
- MenuUnfoldOutlined,
16
- FundOutlined,
17
- FileTextOutlined,
18
- SafetyOutlined,
19
- ApiOutlined
20
- } from '@ant-design/icons';
21
- import './SideMenu.css';
22
-
23
- const { Sider } = Layout;
24
-
25
- const SideMenu = ({ onMenuClick }) => {
26
- const navigate = useNavigate();
27
- const location = useLocation();
28
- const [collapsed, setCollapsed] = useState(false);
29
- const [selectedKeys, setSelectedKeys] = useState([]);
30
-
31
- const menuItems = [
32
- {
33
- key: 'dashboard',
34
- icon: <DashboardOutlined />,
35
- label: '概览',
36
- shortLabel: '概览',
37
- path: '/dashboard',
38
- },
39
- {
40
- key: 'queues',
41
- icon: <AppstoreOutlined />,
42
- label: '任务队列',
43
- shortLabel: '队列',
44
- path: '/queues',
45
- },
46
- {
47
- key: 'scheduled-tasks',
48
- icon: <ClockCircleOutlined />,
49
- label: '定时任务',
50
- shortLabel: '定时',
51
- path: '/scheduled-tasks',
52
- },
53
- {
54
- key: 'alerts',
55
- icon: <AlertOutlined />,
56
- label: '监控告警',
57
- shortLabel: '告警',
58
- path: '/alerts',
59
- },
60
- {
61
- key: 'analytics',
62
- icon: <BarChartOutlined />,
63
- label: '数据分析',
64
- shortLabel: '分析',
65
- path: '/analytics',
66
- },
67
- // {
68
- // key: 'performance',
69
- // icon: <FundOutlined />,
70
- // label: '性能监控',
71
- // shortLabel: '性能',
72
- // path: '/performance',
73
- // },
74
- // {
75
- // key: 'logs',
76
- // icon: <FileTextOutlined />,
77
- // label: '日志查询',
78
- // shortLabel: '日志',
79
- // path: '/logs',
80
- // },
81
- {
82
- key: 'divider2',
83
- type: 'divider',
84
- },
85
- {
86
- key: 'api-docs',
87
- icon: <ApiOutlined />,
88
- label: 'API文档',
89
- shortLabel: 'API',
90
- path: '/api-docs',
91
- },
92
- {
93
- key: 'settings',
94
- icon: <SettingOutlined />,
95
- label: '系统设置',
96
- shortLabel: '设置',
97
- path: '/settings',
98
- },
99
- ];
100
-
101
- useEffect(() => {
102
- const currentItem = menuItems.find(item => item.path === location.pathname);
103
- if (currentItem) {
104
- setSelectedKeys([currentItem.key]);
105
- }
106
- }, [location.pathname]);
107
-
108
- const handleMenuClick = ({ key }) => {
109
- // 查找菜单项(包括子菜单项)
110
- let targetItem = null;
111
- for (const item of menuItems) {
112
- if (item.key === key) {
113
- targetItem = item;
114
- break;
115
- }
116
- if (item.children) {
117
- const childItem = item.children.find(child => child.key === key);
118
- if (childItem) {
119
- targetItem = childItem;
120
- break;
121
- }
122
- }
123
- }
124
-
125
- if (targetItem && targetItem.path) {
126
- navigate(targetItem.path);
127
- if (onMenuClick) {
128
- onMenuClick(targetItem);
129
- }
130
- }
131
- };
132
-
133
- return (
134
- <Sider
135
- trigger={null}
136
- collapsible
137
- collapsed={false}
138
- className="app-sider"
139
- width={64}
140
- style={{
141
- background: '#1a1d21',
142
- borderRight: '1px solid #303030',
143
- }}
144
- >
145
- <div className="sider-header">
146
- <div className="logo-container">
147
- <span className="logo-icon">A</span>
148
- </div>
149
- </div>
150
-
151
- <Menu
152
- mode="inline"
153
- selectedKeys={selectedKeys}
154
- onClick={handleMenuClick}
155
- className="side-menu compact"
156
- style={{
157
- background: 'transparent',
158
- borderRight: 0,
159
- }}
160
- items={menuItems.map(item => {
161
- if (item.type === 'divider') {
162
- return {
163
- type: 'divider',
164
- style: { margin: '8px 0', borderColor: '#303030' }
165
- };
166
- }
167
-
168
- // 如果有子菜单项
169
- if (item.children) {
170
- return {
171
- key: item.key,
172
- label: (
173
- <Tooltip placement="right" title={item.label}>
174
- <div className="menu-item-content">
175
- <div className="menu-icon-wrapper">
176
- {item.icon}
177
- </div>
178
- <span className="menu-label">{item.shortLabel}</span>
179
- </div>
180
- </Tooltip>
181
- ),
182
- children: item.children.map(child => ({
183
- key: child.key,
184
- label: child.label,
185
- icon: child.icon,
186
- }))
187
- };
188
- }
189
-
190
- return {
191
- key: item.key,
192
- label: (
193
- <Tooltip placement="right" title={item.label}>
194
- <div className="menu-item-content">
195
- <div className="menu-icon-wrapper">
196
- {item.icon}
197
- </div>
198
- <span className="menu-label">{item.shortLabel}</span>
199
- </div>
200
- </Tooltip>
201
- ),
202
- };
203
- })}
204
- />
205
- </Sider>
206
- );
207
- };
208
-
209
- export default SideMenu;
@@ -1,244 +0,0 @@
1
- /* 标签导航容器 */
2
- .tabs-nav-container {
3
- flex: 1;
4
- height: 100%;
5
- display: flex;
6
- align-items: center;
7
- padding: 0;
8
- padding-right: 8px;
9
- overflow: hidden;
10
- position: relative;
11
- }
12
-
13
- /* 标签样式 - 扁平化设计 */
14
- .tabs-nav {
15
- height: 100%;
16
- width: 100%;
17
- }
18
-
19
- .tabs-nav .ant-tabs-nav {
20
- height: 100%;
21
- margin: 0;
22
- background: transparent;
23
- border: none;
24
- display: flex;
25
- align-items: center;
26
- }
27
-
28
- .tabs-nav .ant-tabs-nav::before {
29
- border: none;
30
- }
31
-
32
- .tabs-nav .ant-tabs-nav-wrap {
33
- display: flex;
34
- align-items: center;
35
- height: auto;
36
- }
37
-
38
- .tabs-nav .ant-tabs-nav-list {
39
- height: 48px;
40
- display: flex;
41
- align-items: flex-end;
42
- gap: 2px;
43
- padding-top: 8px;
44
- }
45
-
46
- .tabs-nav .ant-tabs-tab {
47
- background: transparent;
48
- border: none;
49
- border-radius: 4px 4px 0 0;
50
- margin: 0;
51
- padding: 0 12px;
52
- height: 40px;
53
- line-height: 40px;
54
- min-width: 90px;
55
- color: rgba(255, 255, 255, 0.65);
56
- transition: all 0.2s;
57
- }
58
-
59
- /* 第一个标签特殊处理 - 左侧无圆角 */
60
- .tabs-nav .ant-tabs-tab:first-child {
61
- border-top-left-radius: 0;
62
- padding-left: 16px;
63
- }
64
-
65
- .tabs-nav .ant-tabs-tab:hover {
66
- background: rgba(255, 255, 255, 0.08);
67
- color: rgba(255, 255, 255, 0.85);
68
- }
69
-
70
- .tabs-nav .ant-tabs-tab-active {
71
- background: #f0f2f5;
72
- color: #262626;
73
- position: relative;
74
- border-left: 1px solid #d9d9d9;
75
- border-top: 1px solid #d9d9d9;
76
- border-right: 1px solid #d9d9d9;
77
- border-bottom: 1px solid #f0f2f5;
78
- font-weight: 500;
79
- z-index: 20;
80
- height: 41px;
81
- padding: 0 12px;
82
- margin-bottom: -1px;
83
- }
84
-
85
- /* 第一个激活标签左侧无边框 */
86
- .tabs-nav .ant-tabs-tab-active:first-child {
87
- padding-left: 16px;
88
- border-left: none;
89
- }
90
-
91
- .tabs-nav .ant-tabs-tab-active:hover {
92
- background: #f0f2f5;
93
- color: #262626;
94
- }
95
-
96
- .tabs-nav .ant-tabs-tab-btn {
97
- color: inherit;
98
- }
99
-
100
- /* 标签内容样式 */
101
- .tab-label {
102
- display: inline-flex;
103
- align-items: center;
104
- gap: 4px;
105
- user-select: none;
106
- font-size: 13px;
107
- white-space: nowrap;
108
- line-height: 1;
109
- }
110
-
111
- /* 概览标签特殊样式 - 居中显示 */
112
- .tab-label-center {
113
- justify-content: center;
114
- width: 100%;
115
- text-align: center;
116
- }
117
-
118
- .tab-icon {
119
- display: inline-flex;
120
- align-items: center;
121
- font-size: 12px;
122
- opacity: 0.8;
123
- }
124
-
125
- /* 关闭按钮样式 */
126
- .tabs-nav .ant-tabs-tab-remove {
127
- margin-left: 8px;
128
- margin-right: -6px;
129
- color: rgba(255, 255, 255, 0.45);
130
- font-size: 10px;
131
- transition: all 0.2s;
132
- padding: 0;
133
- display: inline-flex;
134
- align-items: center;
135
- justify-content: center;
136
- width: 12px;
137
- height: 12px;
138
- opacity: 0;
139
- visibility: hidden;
140
- }
141
-
142
- /* 鼠标悬停在标签上时显示关闭按钮 */
143
- .tabs-nav .ant-tabs-tab:hover .ant-tabs-tab-remove {
144
- opacity: 1;
145
- visibility: visible;
146
- }
147
-
148
- .tabs-nav .ant-tabs-tab-remove:hover {
149
- color: rgba(255, 255, 255, 0.85);
150
- background: rgba(255, 255, 255, 0.1);
151
- border-radius: 2px;
152
- }
153
-
154
- /* 激活标签的关闭按钮 - 始终显示 */
155
- .tabs-nav .ant-tabs-tab-active .ant-tabs-tab-remove {
156
- color: rgba(0, 0, 0, 0.45);
157
- opacity: 1;
158
- visibility: visible;
159
- }
160
-
161
- .tabs-nav .ant-tabs-tab-active .ant-tabs-tab-remove:hover {
162
- color: rgba(0, 0, 0, 0.65);
163
- background: rgba(0, 0, 0, 0.06);
164
- }
165
-
166
- /* 禁用Ant Design的卡片样式 */
167
- .tabs-nav.ant-tabs-card > .ant-tabs-nav .ant-tabs-tab,
168
- .tabs-nav.ant-tabs-editable-card > .ant-tabs-nav .ant-tabs-tab {
169
- background: transparent;
170
- border: none;
171
- }
172
-
173
- .tabs-nav.ant-tabs-card > .ant-tabs-nav .ant-tabs-tab-active,
174
- .tabs-nav.ant-tabs-editable-card > .ant-tabs-nav .ant-tabs-tab-active {
175
- background: #f0f2f5;
176
- border-left: 1px solid #d9d9d9;
177
- border-top: 1px solid #d9d9d9;
178
- border-right: 1px solid #d9d9d9;
179
- border-bottom: 1px solid #f0f2f5;
180
- margin-bottom: -1px;
181
- }
182
-
183
- /* 导航操作按钮 */
184
- .tabs-nav .ant-tabs-nav-operations {
185
- display: none;
186
- }
187
-
188
- /* 标签ink bar隐藏 */
189
- .tabs-nav .ant-tabs-ink-bar {
190
- display: none;
191
- }
192
-
193
- /* 滚动条样式 */
194
- .tabs-nav .ant-tabs-nav-wrap {
195
- overflow: hidden;
196
- }
197
-
198
- .tabs-nav .ant-tabs-nav-list {
199
- transition: transform 0.3s;
200
- }
201
-
202
- /* 上下文菜单样式 */
203
- .ant-dropdown-menu {
204
- min-width: 120px;
205
- }
206
-
207
- .ant-dropdown-menu-item {
208
- padding: 8px 12px;
209
- }
210
-
211
- .ant-dropdown-menu-item .anticon {
212
- margin-right: 8px;
213
- }
214
-
215
- /* 移除多余的边距和填充 */
216
- .tabs-nav.ant-tabs {
217
- line-height: 1;
218
- }
219
-
220
- .tabs-nav .ant-tabs-content-holder {
221
- display: none;
222
- }
223
-
224
- /* 标签分隔线 - 仅非激活标签显示 */
225
- .tabs-nav .ant-tabs-tab {
226
- position: relative;
227
- }
228
-
229
- .tabs-nav .ant-tabs-tab:not(.ant-tabs-tab-active)::after {
230
- content: '';
231
- position: absolute;
232
- top: 50%;
233
- right: 0;
234
- transform: translateY(-50%);
235
- width: 1px;
236
- height: 14px;
237
- background: rgba(255, 255, 255, 0.08);
238
- }
239
-
240
- .tabs-nav .ant-tabs-tab:last-child::after,
241
- .tabs-nav .ant-tabs-tab-active::after,
242
- .tabs-nav .ant-tabs-tab-active + .ant-tabs-tab::after {
243
- display: none;
244
- }