jettask 0.2.23__py3-none-any.whl → 0.2.24__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 (110) hide show
  1. jettask/__init__.py +2 -0
  2. jettask/cli.py +12 -8
  3. jettask/config/lua_scripts.py +37 -0
  4. jettask/config/nacos_config.py +1 -1
  5. jettask/core/app.py +313 -340
  6. jettask/core/container.py +4 -4
  7. jettask/{persistence → core}/namespace.py +93 -27
  8. jettask/core/task.py +16 -9
  9. jettask/core/unified_manager_base.py +136 -26
  10. jettask/db/__init__.py +67 -0
  11. jettask/db/base.py +137 -0
  12. jettask/{utils/db_connector.py → db/connector.py} +130 -26
  13. jettask/db/models/__init__.py +16 -0
  14. jettask/db/models/scheduled_task.py +196 -0
  15. jettask/db/models/task.py +77 -0
  16. jettask/db/models/task_run.py +85 -0
  17. jettask/executor/__init__.py +0 -15
  18. jettask/executor/core.py +76 -31
  19. jettask/executor/process_entry.py +29 -114
  20. jettask/executor/task_executor.py +4 -0
  21. jettask/messaging/event_pool.py +928 -685
  22. jettask/messaging/scanner.py +30 -0
  23. jettask/persistence/__init__.py +28 -103
  24. jettask/persistence/buffer.py +170 -0
  25. jettask/persistence/consumer.py +330 -249
  26. jettask/persistence/manager.py +304 -0
  27. jettask/persistence/persistence.py +391 -0
  28. jettask/scheduler/__init__.py +15 -3
  29. jettask/scheduler/{task_crud.py → database.py} +61 -57
  30. jettask/scheduler/loader.py +2 -2
  31. jettask/scheduler/{scheduler_coordinator.py → manager.py} +23 -6
  32. jettask/scheduler/models.py +14 -10
  33. jettask/scheduler/schedule.py +166 -0
  34. jettask/scheduler/scheduler.py +12 -11
  35. jettask/schemas/__init__.py +50 -1
  36. jettask/schemas/backlog.py +43 -6
  37. jettask/schemas/namespace.py +70 -19
  38. jettask/schemas/queue.py +19 -3
  39. jettask/schemas/responses.py +493 -0
  40. jettask/task/__init__.py +0 -2
  41. jettask/task/router.py +3 -0
  42. jettask/test_connection_monitor.py +1 -1
  43. jettask/utils/__init__.py +7 -5
  44. jettask/utils/db_init.py +8 -4
  45. jettask/utils/namespace_dep.py +167 -0
  46. jettask/utils/queue_matcher.py +186 -0
  47. jettask/utils/rate_limit/concurrency_limiter.py +7 -1
  48. jettask/utils/stream_backlog.py +1 -1
  49. jettask/webui/__init__.py +0 -1
  50. jettask/webui/api/__init__.py +4 -4
  51. jettask/webui/api/alerts.py +806 -71
  52. jettask/webui/api/example_refactored.py +400 -0
  53. jettask/webui/api/namespaces.py +390 -45
  54. jettask/webui/api/overview.py +300 -54
  55. jettask/webui/api/queues.py +971 -267
  56. jettask/webui/api/scheduled.py +1249 -56
  57. jettask/webui/api/settings.py +129 -7
  58. jettask/webui/api/workers.py +442 -0
  59. jettask/webui/app.py +46 -2329
  60. jettask/webui/middleware/__init__.py +6 -0
  61. jettask/webui/middleware/namespace_middleware.py +135 -0
  62. jettask/webui/services/__init__.py +146 -0
  63. jettask/webui/services/heartbeat_service.py +251 -0
  64. jettask/webui/services/overview_service.py +60 -51
  65. jettask/webui/services/queue_monitor_service.py +426 -0
  66. jettask/webui/services/redis_monitor_service.py +87 -0
  67. jettask/webui/services/settings_service.py +174 -111
  68. jettask/webui/services/task_monitor_service.py +222 -0
  69. jettask/webui/services/timeline_pg_service.py +452 -0
  70. jettask/webui/services/timeline_service.py +189 -0
  71. jettask/webui/services/worker_monitor_service.py +467 -0
  72. jettask/webui/utils/__init__.py +11 -0
  73. jettask/webui/utils/time_utils.py +122 -0
  74. jettask/worker/lifecycle.py +8 -2
  75. {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/METADATA +1 -1
  76. jettask-0.2.24.dist-info/RECORD +142 -0
  77. jettask/executor/executor.py +0 -338
  78. jettask/persistence/backlog_monitor.py +0 -567
  79. jettask/persistence/base.py +0 -2334
  80. jettask/persistence/db_manager.py +0 -516
  81. jettask/persistence/maintenance.py +0 -81
  82. jettask/persistence/message_consumer.py +0 -259
  83. jettask/persistence/models.py +0 -49
  84. jettask/persistence/offline_recovery.py +0 -196
  85. jettask/persistence/queue_discovery.py +0 -215
  86. jettask/persistence/task_persistence.py +0 -218
  87. jettask/persistence/task_updater.py +0 -583
  88. jettask/scheduler/add_execution_count.sql +0 -11
  89. jettask/scheduler/add_priority_field.sql +0 -26
  90. jettask/scheduler/add_scheduler_id.sql +0 -25
  91. jettask/scheduler/add_scheduler_id_index.sql +0 -10
  92. jettask/scheduler/make_scheduler_id_required.sql +0 -28
  93. jettask/scheduler/migrate_interval_seconds.sql +0 -9
  94. jettask/scheduler/performance_optimization.sql +0 -45
  95. jettask/scheduler/run_scheduler.py +0 -186
  96. jettask/scheduler/schema.sql +0 -84
  97. jettask/task/task_executor.py +0 -318
  98. jettask/webui/api/analytics.py +0 -323
  99. jettask/webui/config.py +0 -90
  100. jettask/webui/models/__init__.py +0 -3
  101. jettask/webui/models/namespace.py +0 -63
  102. jettask/webui/namespace_manager/__init__.py +0 -10
  103. jettask/webui/namespace_manager/multi.py +0 -593
  104. jettask/webui/namespace_manager/unified.py +0 -193
  105. jettask/webui/run.py +0 -46
  106. jettask-0.2.23.dist-info/RECORD +0 -145
  107. {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/WHEEL +0 -0
  108. {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/entry_points.txt +0 -0
  109. {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/licenses/LICENSE +0 -0
  110. {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,493 @@
1
+ """
2
+ API 响应模型定义
3
+ 包含所有 API 接口的响应模型和示例数据
4
+ """
5
+ from typing import Optional, List, Dict, Any
6
+ from datetime import datetime
7
+ from pydantic import BaseModel, Field, ConfigDict
8
+
9
+
10
+ # ============ 通用响应模型 ============
11
+
12
+ class SuccessResponse(BaseModel):
13
+ """通用成功响应"""
14
+ success: bool = Field(default=True, description="请求是否成功")
15
+ message: Optional[str] = Field(None, description="响应消息")
16
+
17
+ model_config = ConfigDict(json_schema_extra={
18
+ "example": {
19
+ "success": True,
20
+ "message": "操作成功"
21
+ }
22
+ })
23
+
24
+
25
+ class DataResponse(BaseModel):
26
+ """通用数据响应"""
27
+ success: bool = Field(default=True, description="请求是否成功")
28
+ data: Any = Field(..., description="响应数据")
29
+ message: Optional[str] = Field(None, description="响应消息")
30
+
31
+ model_config = ConfigDict(json_schema_extra={
32
+ "example": {
33
+ "success": True,
34
+ "data": {},
35
+ "message": "获取成功"
36
+ }
37
+ })
38
+
39
+
40
+ class PaginatedDataResponse(BaseModel):
41
+ """分页数据响应"""
42
+ success: bool = Field(default=True, description="请求是否成功")
43
+ data: List[Any] = Field(default=[], description="数据列表")
44
+ total: int = Field(..., description="总记录数", ge=0)
45
+ page: int = Field(..., description="当前页码", ge=1)
46
+ page_size: int = Field(..., description="每页大小", ge=1, le=100)
47
+
48
+ model_config = ConfigDict(json_schema_extra={
49
+ "example": {
50
+ "success": True,
51
+ "data": [],
52
+ "total": 0,
53
+ "page": 1,
54
+ "page_size": 20
55
+ }
56
+ })
57
+
58
+
59
+ # ============ Overview 模块响应模型 ============
60
+
61
+ class SystemStatsData(BaseModel):
62
+ """系统统计数据"""
63
+ total_queues: int = Field(..., description="队列总数", ge=0)
64
+ total_tasks: int = Field(..., description="任务总数", ge=0)
65
+ active_workers: int = Field(..., description="活跃 Worker 数", ge=0)
66
+ pending_tasks: int = Field(..., description="待处理任务数", ge=0)
67
+ processing_tasks: int = Field(..., description="处理中任务数", ge=0)
68
+ completed_tasks: int = Field(..., description="已完成任务数", ge=0)
69
+ failed_tasks: int = Field(..., description="失败任务数", ge=0)
70
+
71
+ model_config = ConfigDict(json_schema_extra={
72
+ "example": {
73
+ "total_queues": 5,
74
+ "total_tasks": 1250,
75
+ "active_workers": 12,
76
+ "pending_tasks": 45,
77
+ "processing_tasks": 8,
78
+ "completed_tasks": 1180,
79
+ "failed_tasks": 17
80
+ }
81
+ })
82
+
83
+
84
+ class SystemStatsResponse(BaseModel):
85
+ """系统统计响应"""
86
+ success: bool = Field(default=True, description="请求是否成功")
87
+ data: SystemStatsData = Field(..., description="系统统计数据")
88
+ namespace: str = Field(..., description="命名空间")
89
+ timestamp: datetime = Field(default_factory=datetime.now, description="统计时间")
90
+
91
+ model_config = ConfigDict(json_schema_extra={
92
+ "example": {
93
+ "success": True,
94
+ "data": {
95
+ "total_queues": 5,
96
+ "total_tasks": 1250,
97
+ "active_workers": 12,
98
+ "pending_tasks": 45,
99
+ "processing_tasks": 8,
100
+ "completed_tasks": 1180,
101
+ "failed_tasks": 17
102
+ },
103
+ "namespace": "default",
104
+ "timestamp": "2025-10-18T10:30:00Z"
105
+ }
106
+ })
107
+
108
+
109
+ class DashboardStatsData(BaseModel):
110
+ """仪表板统计数据"""
111
+ total_tasks: int = Field(..., description="任务总数", ge=0)
112
+ success_count: int = Field(..., description="成功任务数", ge=0)
113
+ failed_count: int = Field(..., description="失败任务数", ge=0)
114
+ success_rate: float = Field(..., description="成功率 (0-100)", ge=0, le=100)
115
+ throughput: float = Field(..., description="吞吐量 (任务/秒)", ge=0)
116
+ avg_processing_time: float = Field(..., description="平均处理时间 (秒)", ge=0)
117
+
118
+ model_config = ConfigDict(json_schema_extra={
119
+ "example": {
120
+ "total_tasks": 1250,
121
+ "success_count": 1180,
122
+ "failed_count": 17,
123
+ "success_rate": 94.4,
124
+ "throughput": 12.5,
125
+ "avg_processing_time": 2.3
126
+ }
127
+ })
128
+
129
+
130
+ class DashboardStatsResponse(BaseModel):
131
+ """仪表板统计响应"""
132
+ success: bool = Field(default=True, description="请求是否成功")
133
+ data: DashboardStatsData = Field(..., description="仪表板统计数据")
134
+ namespace: str = Field(..., description="命名空间")
135
+ time_range: str = Field(..., description="时间范围")
136
+
137
+ model_config = ConfigDict(json_schema_extra={
138
+ "example": {
139
+ "success": True,
140
+ "data": {
141
+ "total_tasks": 1250,
142
+ "success_count": 1180,
143
+ "failed_count": 17,
144
+ "success_rate": 94.4,
145
+ "throughput": 12.5,
146
+ "avg_processing_time": 2.3
147
+ },
148
+ "namespace": "default",
149
+ "time_range": "24h"
150
+ }
151
+ })
152
+
153
+
154
+ class QueueRankingItem(BaseModel):
155
+ """队列排行项"""
156
+ queue_name: str = Field(..., description="队列名称")
157
+ value: float = Field(..., description="指标值", ge=0)
158
+ rank: int = Field(..., description="排名", ge=1)
159
+
160
+ model_config = ConfigDict(json_schema_extra={
161
+ "example": {
162
+ "queue_name": "email_queue",
163
+ "value": 150.5,
164
+ "rank": 1
165
+ }
166
+ })
167
+
168
+
169
+ class TopQueuesResponse(BaseModel):
170
+ """队列排行榜响应"""
171
+ success: bool = Field(default=True, description="请求是否成功")
172
+ data: List[QueueRankingItem] = Field(..., description="排行榜数据")
173
+ metric: str = Field(..., description="指标类型 (backlog/error)")
174
+ namespace: str = Field(..., description="命名空间")
175
+ time_range: str = Field(..., description="时间范围")
176
+
177
+ model_config = ConfigDict(json_schema_extra={
178
+ "example": {
179
+ "success": True,
180
+ "data": [
181
+ {"queue_name": "email_queue", "value": 150, "rank": 1},
182
+ {"queue_name": "sms_queue", "value": 89, "rank": 2},
183
+ {"queue_name": "push_queue", "value": 45, "rank": 3}
184
+ ],
185
+ "metric": "backlog",
186
+ "namespace": "default",
187
+ "time_range": "24h"
188
+ }
189
+ })
190
+
191
+
192
+ # ============ Namespaces 模块响应模型 ============
193
+
194
+ class NamespaceStatistics(BaseModel):
195
+ """命名空间统计信息"""
196
+ total_queues: int = Field(..., description="队列总数", ge=0)
197
+ total_tasks: int = Field(..., description="任务总数", ge=0)
198
+ active_workers: int = Field(..., description="活跃 Worker 数", ge=0)
199
+ redis_memory_usage: Optional[int] = Field(None, description="Redis 内存使用 (bytes)", ge=0)
200
+ db_connections: Optional[int] = Field(None, description="数据库连接数", ge=0)
201
+
202
+ model_config = ConfigDict(json_schema_extra={
203
+ "example": {
204
+ "total_queues": 5,
205
+ "total_tasks": 1250,
206
+ "active_workers": 12,
207
+ "redis_memory_usage": 10485760,
208
+ "db_connections": 5
209
+ }
210
+ })
211
+
212
+
213
+ class NamespaceStatisticsResponse(BaseModel):
214
+ """命名空间统计响应"""
215
+ success: bool = Field(default=True, description="请求是否成功")
216
+ data: NamespaceStatistics = Field(..., description="统计数据")
217
+ namespace: str = Field(..., description="命名空间名称")
218
+
219
+ model_config = ConfigDict(json_schema_extra={
220
+ "example": {
221
+ "success": True,
222
+ "data": {
223
+ "total_queues": 5,
224
+ "total_tasks": 1250,
225
+ "active_workers": 12,
226
+ "redis_memory_usage": 10485760,
227
+ "db_connections": 5
228
+ },
229
+ "namespace": "default"
230
+ }
231
+ })
232
+
233
+
234
+ # ============ Workers 模块响应模型 ============
235
+
236
+ class WorkerHeartbeatInfo(BaseModel):
237
+ """Worker 心跳信息"""
238
+ worker_id: str = Field(..., description="Worker ID")
239
+ queue_name: str = Field(..., description="队列名称")
240
+ status: str = Field(..., description="状态 (online/offline)")
241
+ last_heartbeat: datetime = Field(..., description="最后心跳时间")
242
+ tasks_processed: int = Field(..., description="已处理任务数", ge=0)
243
+ current_task: Optional[str] = Field(None, description="当前处理的任务 ID")
244
+
245
+ model_config = ConfigDict(json_schema_extra={
246
+ "example": {
247
+ "worker_id": "worker-001",
248
+ "queue_name": "email_queue",
249
+ "status": "online",
250
+ "last_heartbeat": "2025-10-18T10:30:00Z",
251
+ "tasks_processed": 150,
252
+ "current_task": "task-12345"
253
+ }
254
+ })
255
+
256
+
257
+ class WorkersResponse(BaseModel):
258
+ """Workers 列表响应"""
259
+ success: bool = Field(default=True, description="请求是否成功")
260
+ namespace: str = Field(..., description="命名空间")
261
+ queue: str = Field(..., description="队列名称")
262
+ workers: List[WorkerHeartbeatInfo] = Field(..., description="Worker 列表")
263
+
264
+ model_config = ConfigDict(json_schema_extra={
265
+ "example": {
266
+ "success": True,
267
+ "namespace": "default",
268
+ "queue": "email_queue",
269
+ "workers": [
270
+ {
271
+ "worker_id": "worker-001",
272
+ "queue_name": "email_queue",
273
+ "status": "online",
274
+ "last_heartbeat": "2025-10-18T10:30:00Z",
275
+ "tasks_processed": 150,
276
+ "current_task": "task-12345"
277
+ }
278
+ ]
279
+ }
280
+ })
281
+
282
+
283
+ class WorkerSummary(BaseModel):
284
+ """Worker 汇总统计"""
285
+ total_workers: int = Field(..., description="总 Worker 数", ge=0)
286
+ online_workers: int = Field(..., description="在线 Worker 数", ge=0)
287
+ offline_workers: int = Field(..., description="离线 Worker 数", ge=0)
288
+ total_tasks_processed: int = Field(..., description="总处理任务数", ge=0)
289
+ avg_tasks_per_worker: float = Field(..., description="平均每个 Worker 处理任务数", ge=0)
290
+
291
+ model_config = ConfigDict(json_schema_extra={
292
+ "example": {
293
+ "total_workers": 12,
294
+ "online_workers": 10,
295
+ "offline_workers": 2,
296
+ "total_tasks_processed": 1500,
297
+ "avg_tasks_per_worker": 125.0
298
+ }
299
+ })
300
+
301
+
302
+ class WorkerSummaryResponse(BaseModel):
303
+ """Worker 汇总统计响应"""
304
+ success: bool = Field(default=True, description="请求是否成功")
305
+ namespace: str = Field(..., description="命名空间")
306
+ queue: str = Field(..., description="队列名称")
307
+ summary: WorkerSummary = Field(..., description="汇总统计")
308
+
309
+ model_config = ConfigDict(json_schema_extra={
310
+ "example": {
311
+ "success": True,
312
+ "namespace": "default",
313
+ "queue": "email_queue",
314
+ "summary": {
315
+ "total_workers": 12,
316
+ "online_workers": 10,
317
+ "offline_workers": 2,
318
+ "total_tasks_processed": 1500,
319
+ "avg_tasks_per_worker": 125.0
320
+ }
321
+ }
322
+ })
323
+
324
+
325
+ class WorkerOfflineRecord(BaseModel):
326
+ """Worker 离线记录"""
327
+ worker_id: str = Field(..., description="Worker ID")
328
+ queue_name: str = Field(..., description="队列名称")
329
+ offline_time: datetime = Field(..., description="离线时间")
330
+ last_task: Optional[str] = Field(None, description="最后处理的任务 ID")
331
+ reason: Optional[str] = Field(None, description="离线原因")
332
+
333
+ model_config = ConfigDict(json_schema_extra={
334
+ "example": {
335
+ "worker_id": "worker-002",
336
+ "queue_name": "email_queue",
337
+ "offline_time": "2025-10-18T09:30:00Z",
338
+ "last_task": "task-12340",
339
+ "reason": "heartbeat_timeout"
340
+ }
341
+ })
342
+
343
+
344
+ class WorkerOfflineHistoryResponse(BaseModel):
345
+ """Worker 离线历史响应"""
346
+ success: bool = Field(default=True, description="请求是否成功")
347
+ history: List[WorkerOfflineRecord] = Field(..., description="离线历史记录")
348
+ total: int = Field(..., description="总记录数", ge=0)
349
+
350
+ model_config = ConfigDict(json_schema_extra={
351
+ "example": {
352
+ "success": True,
353
+ "history": [
354
+ {
355
+ "worker_id": "worker-002",
356
+ "queue_name": "email_queue",
357
+ "offline_time": "2025-10-18T09:30:00Z",
358
+ "last_task": "task-12340",
359
+ "reason": "heartbeat_timeout"
360
+ }
361
+ ],
362
+ "total": 1
363
+ }
364
+ })
365
+
366
+
367
+ # ============ Settings 模块响应模型 ============
368
+
369
+ class DatabaseStatus(BaseModel):
370
+ """数据库状态"""
371
+ connected: bool = Field(..., description="是否已连接")
372
+ host: Optional[str] = Field(None, description="主机地址")
373
+ port: Optional[int] = Field(None, description="端口")
374
+ database: Optional[str] = Field(None, description="数据库名称")
375
+ pool_size: Optional[int] = Field(None, description="连接池大小", ge=0)
376
+ active_connections: Optional[int] = Field(None, description="活跃连接数", ge=0)
377
+
378
+ model_config = ConfigDict(json_schema_extra={
379
+ "example": {
380
+ "connected": True,
381
+ "host": "localhost",
382
+ "port": 5432,
383
+ "database": "jettask",
384
+ "pool_size": 10,
385
+ "active_connections": 3
386
+ }
387
+ })
388
+
389
+
390
+ class SystemSettings(BaseModel):
391
+ """系统设置"""
392
+ api_version: str = Field(..., description="API 版本")
393
+ service_name: str = Field(..., description="服务名称")
394
+ environment: str = Field(..., description="运行环境 (development/staging/production)")
395
+ debug_mode: bool = Field(..., description="是否开启调试模式")
396
+ database: DatabaseStatus = Field(..., description="数据库状态")
397
+
398
+ model_config = ConfigDict(json_schema_extra={
399
+ "example": {
400
+ "api_version": "v1",
401
+ "service_name": "JetTask WebUI",
402
+ "environment": "development",
403
+ "debug_mode": True,
404
+ "database": {
405
+ "connected": True,
406
+ "host": "localhost",
407
+ "port": 5432,
408
+ "database": "jettask",
409
+ "pool_size": 10,
410
+ "active_connections": 3
411
+ }
412
+ }
413
+ })
414
+
415
+
416
+ class SystemSettingsResponse(BaseModel):
417
+ """系统设置响应"""
418
+ success: bool = Field(default=True, description="请求是否成功")
419
+ data: SystemSettings = Field(..., description="系统设置")
420
+
421
+ model_config = ConfigDict(json_schema_extra={
422
+ "example": {
423
+ "success": True,
424
+ "data": {
425
+ "api_version": "v1",
426
+ "service_name": "JetTask WebUI",
427
+ "environment": "development",
428
+ "debug_mode": True,
429
+ "database": {
430
+ "connected": True,
431
+ "host": "localhost",
432
+ "port": 5432,
433
+ "database": "jettask",
434
+ "pool_size": 10,
435
+ "active_connections": 3
436
+ }
437
+ }
438
+ }
439
+ })
440
+
441
+
442
+ class DatabaseStatusResponse(BaseModel):
443
+ """数据库状态响应"""
444
+ success: bool = Field(default=True, description="请求是否成功")
445
+ data: DatabaseStatus = Field(..., description="数据库状态")
446
+
447
+ model_config = ConfigDict(json_schema_extra={
448
+ "example": {
449
+ "success": True,
450
+ "data": {
451
+ "connected": True,
452
+ "host": "localhost",
453
+ "port": 5432,
454
+ "database": "jettask",
455
+ "pool_size": 10,
456
+ "active_connections": 3
457
+ }
458
+ }
459
+ })
460
+
461
+
462
+ __all__ = [
463
+ # 通用响应
464
+ 'SuccessResponse',
465
+ 'DataResponse',
466
+ 'PaginatedDataResponse',
467
+
468
+ # Overview
469
+ 'SystemStatsData',
470
+ 'SystemStatsResponse',
471
+ 'DashboardStatsData',
472
+ 'DashboardStatsResponse',
473
+ 'QueueRankingItem',
474
+ 'TopQueuesResponse',
475
+
476
+ # Namespaces
477
+ 'NamespaceStatistics',
478
+ 'NamespaceStatisticsResponse',
479
+
480
+ # Workers
481
+ 'WorkerHeartbeatInfo',
482
+ 'WorkersResponse',
483
+ 'WorkerSummary',
484
+ 'WorkerSummaryResponse',
485
+ 'WorkerOfflineRecord',
486
+ 'WorkerOfflineHistoryResponse',
487
+
488
+ # Settings
489
+ 'DatabaseStatus',
490
+ 'SystemSettings',
491
+ 'SystemSettingsResponse',
492
+ 'DatabaseStatusResponse',
493
+ ]
jettask/task/__init__.py CHANGED
@@ -5,12 +5,10 @@
5
5
  """
6
6
 
7
7
  from .task_registry import TaskRegistry, TaskDefinition
8
- from .task_executor import TaskExecutor
9
8
  from .router import TaskRouter
10
9
 
11
10
  __all__ = [
12
11
  'TaskRegistry',
13
12
  'TaskDefinition',
14
- 'TaskExecutor',
15
13
  'TaskRouter',
16
14
  ]
jettask/task/router.py CHANGED
@@ -72,6 +72,7 @@ class TaskRouter:
72
72
  max_retries: int = None,
73
73
  retry_delay: int = None,
74
74
  rate_limit: RateLimitConfig = None,
75
+ auto_ack: bool = True,
75
76
  **kwargs
76
77
  ):
77
78
  """
@@ -84,6 +85,7 @@ class TaskRouter:
84
85
  max_retries: 最大重试次数
85
86
  retry_delay: 重试延迟
86
87
  rate_limit: 限流配置(QPSLimit 或 ConcurrencyLimit)
88
+ auto_ack: 是否自动ACK消息(默认True),设为False时需要手动调用ack()
87
89
  **kwargs: 其他任务参数
88
90
 
89
91
  Example:
@@ -118,6 +120,7 @@ class TaskRouter:
118
120
  'max_retries': max_retries or self.default_max_retries,
119
121
  'retry_delay': retry_delay or self.default_retry_delay,
120
122
  'rate_limit': rate_limit,
123
+ 'auto_ack': auto_ack,
121
124
  'tags': self.tags,
122
125
  **kwargs
123
126
  }
@@ -4,7 +4,7 @@
4
4
  """
5
5
  import time
6
6
  import logging
7
- from jettask.utils.db_connector import (
7
+ from jettask.db.connector import (
8
8
  get_sync_redis_client,
9
9
  get_async_redis_client,
10
10
  start_connection_monitor,
jettask/utils/__init__.py CHANGED
@@ -1,6 +1,10 @@
1
1
  from .helpers import get_hostname, gen_task_name, is_async_function
2
- from .db_connector import (
3
- # 全局连接池函数(推荐使用)
2
+ from .file_watcher import FileChangeHandler
3
+ from .task_logger import get_task_logger
4
+
5
+ # 为了向后兼容,从 jettask.db 重新导出数据库连接函数
6
+ from jettask.db.connector import (
7
+ # 全局连接池函数
4
8
  get_sync_redis_pool,
5
9
  get_async_redis_pool,
6
10
  get_pg_engine_and_factory,
@@ -11,14 +15,12 @@ from .db_connector import (
11
15
  # 配置解析
12
16
  DBConfig,
13
17
  )
14
- from .file_watcher import FileChangeHandler
15
- from .task_logger import get_task_logger
16
18
 
17
19
  __all__ = [
18
20
  "get_hostname",
19
21
  "gen_task_name",
20
22
  "is_async_function",
21
- # 全局连接池函数(推荐使用)
23
+ # 全局连接池函数(向后兼容)
22
24
  "get_sync_redis_pool",
23
25
  "get_async_redis_pool",
24
26
  "get_pg_engine_and_factory",
jettask/utils/db_init.py CHANGED
@@ -2,20 +2,24 @@
2
2
 
3
3
  import asyncio
4
4
  import logging
5
+ import os
5
6
  import sys
6
7
  from pathlib import Path
7
8
 
8
9
  import asyncpg
9
10
 
10
- from jettask.webui.config import PostgreSQLConfig
11
-
12
11
  logger = logging.getLogger(__name__)
13
12
 
14
13
 
15
14
  class DatabaseInitializer:
16
15
  """数据库初始化器 - 支持分区表"""
17
-
18
- def __init__(self, pg_config: PostgreSQLConfig):
16
+
17
+ def __init__(self, pg_config):
18
+ """初始化数据库初始化器
19
+
20
+ Args:
21
+ pg_config: PostgreSQL配置(字典或对象),需包含 host, port, database, user, password 属性
22
+ """
19
23
  self.pg_config = pg_config
20
24
  self.schema_path = Path(__file__).parent / "sql" / "init_database.sql"
21
25