jettask 0.2.20__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 +4 -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.20.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.20.dist-info/RECORD +0 -145
  107. {jettask-0.2.20.dist-info → jettask-0.2.24.dist-info}/WHEEL +0 -0
  108. {jettask-0.2.20.dist-info → jettask-0.2.24.dist-info}/entry_points.txt +0 -0
  109. {jettask-0.2.20.dist-info → jettask-0.2.24.dist-info}/licenses/LICENSE +0 -0
  110. {jettask-0.2.20.dist-info → jettask-0.2.24.dist-info}/top_level.txt +0 -0
@@ -3,22 +3,59 @@
3
3
  """
4
4
  from typing import Optional, List, Dict, Any
5
5
  from datetime import datetime
6
- from pydantic import BaseModel, Field
6
+ from pydantic import BaseModel, Field, ConfigDict
7
+
8
+
9
+ class BacklogLatestRequest(BaseModel):
10
+ """获取最新积压数据请求模型"""
11
+ queues: Optional[List[str]] = Field(None, description="队列名称列表,为空时返回所有队列")
12
+
13
+ model_config = ConfigDict(json_schema_extra={
14
+ "examples": [
15
+ {
16
+ "queues": ["email_queue", "sms_queue"]
17
+ },
18
+ {
19
+ "queues": []
20
+ }
21
+ ]
22
+ })
7
23
 
8
24
 
9
25
  class BacklogTrendRequest(BaseModel):
10
26
  """积压趋势请求模型"""
11
- namespace: str = Field(..., description="命名空间")
12
27
  queue_name: Optional[str] = Field(None, description="队列名称,为空时查询所有队列")
13
- start_time: Optional[str] = Field(None, description="开始时间")
14
- end_time: Optional[str] = Field(None, description="结束时间")
15
- time_range: Optional[str] = Field(None, description="时间范围,如 '1h', '6h', '1d', '7d'")
16
- interval: str = Field(default="5m", description="数据聚合间隔")
28
+ time_range: Optional[str] = Field("1h", description="时间范围,如 '1h', '6h', '1d', '7d'")
29
+ start_time: Optional[str] = Field(None, description="开始时间(ISO格式)")
30
+ end_time: Optional[str] = Field(None, description="结束时间(ISO格式)")
31
+ interval: str = Field(default="5m", description="数据聚合间隔,如 '1m', '5m', '1h'")
17
32
  metrics: List[str] = Field(
18
33
  default=["pending", "processing", "completed", "failed"],
19
34
  description="要查询的指标类型"
20
35
  )
21
36
 
37
+ model_config = ConfigDict(json_schema_extra={
38
+ "examples": [
39
+ {
40
+ "queue_name": "email_queue",
41
+ "time_range": "1h",
42
+ "interval": "5m",
43
+ "metrics": ["pending", "processing"]
44
+ },
45
+ {
46
+ "queue_name": "sms_queue",
47
+ "start_time": "2025-10-18T09:00:00Z",
48
+ "end_time": "2025-10-18T10:00:00Z",
49
+ "interval": "1m",
50
+ "metrics": ["pending", "processing", "completed", "failed"]
51
+ },
52
+ {
53
+ "time_range": "24h",
54
+ "interval": "1h"
55
+ }
56
+ ]
57
+ })
58
+
22
59
 
23
60
  class BacklogSnapshot(BaseModel):
24
61
  """积压快照模型"""
@@ -3,7 +3,7 @@
3
3
  """
4
4
  from typing import Optional, Dict, Any, List
5
5
  from datetime import datetime
6
- from pydantic import BaseModel, Field
6
+ from pydantic import BaseModel, Field, ConfigDict
7
7
  from enum import Enum
8
8
 
9
9
 
@@ -17,64 +17,115 @@ class NamespaceCreate(BaseModel):
17
17
  """创建命名空间请求模型"""
18
18
  name: str = Field(..., description="命名空间名称")
19
19
  description: Optional[str] = Field(None, description="命名空间描述")
20
-
20
+
21
21
  # 配置模式
22
22
  config_mode: ConfigMode = Field(ConfigMode.DIRECT, description="配置模式: direct(直接配置) 或 nacos(Nacos配置)")
23
-
23
+
24
24
  # Redis配置 - 支持两种方式
25
25
  # 方式1: 直接配置字符串 (格式: redis://[password@]host:port/db)
26
26
  redis_url: Optional[str] = Field(None, description="Redis连接字符串,格式: redis://[password@]host:port/db")
27
27
  # 方式2: Nacos配置键
28
28
  redis_nacos_key: Optional[str] = Field(None, description="Redis连接字符串的Nacos配置键")
29
-
29
+
30
30
  # PostgreSQL配置 - 支持两种方式
31
31
  # 方式1: 直接配置字符串 (格式: postgresql://user:password@host:port/database)
32
32
  pg_url: Optional[str] = Field(None, description="PostgreSQL连接字符串,格式: postgresql://user:password@host:port/database")
33
33
  # 方式2: Nacos配置键
34
34
  pg_nacos_key: Optional[str] = Field(None, description="PostgreSQL连接字符串的Nacos配置键")
35
35
 
36
+ model_config = ConfigDict(json_schema_extra={
37
+ "examples": [
38
+ {
39
+ "name": "production",
40
+ "description": "生产环境命名空间",
41
+ "config_mode": "direct",
42
+ "redis_url": "redis://:password@localhost:6379/0",
43
+ "pg_url": "postgresql://user:password@localhost:5432/jettask"
44
+ },
45
+ {
46
+ "name": "staging",
47
+ "description": "预发布环境命名空间",
48
+ "config_mode": "nacos",
49
+ "redis_nacos_key": "staging.redis.url",
50
+ "pg_nacos_key": "staging.pg.url"
51
+ }
52
+ ]
53
+ })
54
+
36
55
 
37
56
  class NamespaceUpdate(BaseModel):
38
57
  """更新命名空间请求模型"""
39
58
  description: Optional[str] = Field(None, description="命名空间描述")
40
-
59
+
41
60
  # 配置模式
42
61
  config_mode: Optional[ConfigMode] = Field(None, description="配置模式: direct(直接配置) 或 nacos(Nacos配置)")
43
-
62
+
44
63
  # Redis配置 - 支持两种方式
45
64
  redis_url: Optional[str] = Field(None, description="Redis连接字符串,格式: redis://[password@]host:port/db")
46
65
  redis_nacos_key: Optional[str] = Field(None, description="Redis连接字符串的Nacos配置键")
47
-
66
+
48
67
  # PostgreSQL配置 - 支持两种方式
49
68
  pg_url: Optional[str] = Field(None, description="PostgreSQL连接字符串,格式: postgresql://user:password@host:port/database")
50
69
  pg_nacos_key: Optional[str] = Field(None, description="PostgreSQL连接字符串的Nacos配置键")
51
-
70
+
52
71
  enabled: Optional[bool] = Field(None, description="是否启用")
53
72
 
73
+ model_config = ConfigDict(json_schema_extra={
74
+ "examples": [
75
+ {
76
+ "description": "更新命名空间描述",
77
+ "enabled": True
78
+ },
79
+ {
80
+ "config_mode": "direct",
81
+ "redis_url": "redis://:newpassword@localhost:6380/1",
82
+ "enabled": False
83
+ }
84
+ ]
85
+ })
86
+
54
87
 
55
88
  class NamespaceResponse(BaseModel):
56
89
  """命名空间响应模型"""
57
90
  name: str = Field(..., description="命名空间名称")
58
91
  description: Optional[str] = Field(None, description="命名空间描述")
59
-
60
- # Redis配置信息 - 只返回最终的URL
61
- redis_url: str = Field(..., description="Redis连接字符串")
62
-
63
- # PostgreSQL配置信息 - 只返回最终的URL
64
- pg_url: Optional[str] = Field(None, description="PostgreSQL连接字符串")
65
-
92
+
93
+ # Redis配置信息 - 根据配置模式返回不同内容
94
+ redis_url: Optional[str] = Field(None, description="Redis连接字符串(仅 direct 模式时返回完整 URL,nacos 模式为 null)")
95
+ redis_config_mode: str = Field(default="direct", description="Redis 配置模式:direct(直接配置)或 nacos(Nacos 配置中心)")
96
+ redis_nacos_key: Optional[str] = Field(None, description="Redis Nacos 配置键(仅 nacos 模式时返回)")
97
+
98
+ # PostgreSQL配置信息 - 根据配置模式返回不同内容
99
+ pg_url: Optional[str] = Field(None, description="PostgreSQL连接字符串(仅 direct 模式时返回完整 URL,nacos 模式为 null)")
100
+ pg_config_mode: str = Field(default="direct", description="PostgreSQL 配置模式:direct 或 nacos")
101
+ pg_nacos_key: Optional[str] = Field(None, description="PostgreSQL Nacos 配置键(仅 nacos 模式时返回)")
102
+
66
103
  # 连接信息
67
104
  connection_url: str = Field(..., description="用于连接此命名空间的URL路径")
68
105
  version: int = Field(default=1, description="配置版本号")
69
-
106
+
70
107
  enabled: bool = Field(..., description="是否启用")
71
108
  created_at: datetime = Field(..., description="创建时间")
72
109
  updated_at: Optional[datetime] = Field(None, description="更新时间")
73
-
74
- class Config:
75
- json_encoders = {
110
+
111
+ model_config = ConfigDict(
112
+ json_encoders={
76
113
  datetime: lambda v: v.isoformat() if v else None
114
+ },
115
+ json_schema_extra={
116
+ "example": {
117
+ "name": "production",
118
+ "description": "生产环境命名空间",
119
+ "redis_url": "redis://:***@localhost:6379/0",
120
+ "pg_url": "postgresql://user:***@localhost:5432/jettask",
121
+ "connection_url": "/api/v1/namespaces/production",
122
+ "version": 1,
123
+ "enabled": True,
124
+ "created_at": "2025-10-18T10:00:00Z",
125
+ "updated_at": "2025-10-18T12:00:00Z"
126
+ }
77
127
  }
128
+ )
78
129
 
79
130
 
80
131
  class NamespaceInfo(BaseModel):
jettask/schemas/queue.py CHANGED
@@ -3,16 +3,32 @@
3
3
  """
4
4
  from typing import Optional, List, Dict, Any
5
5
  from datetime import datetime
6
- from pydantic import BaseModel, Field
6
+ from pydantic import BaseModel, Field, ConfigDict
7
7
 
8
8
 
9
9
  class TimeRangeQuery(BaseModel):
10
10
  """时间范围查询模型"""
11
11
  queues: Optional[List[str]] = Field(None, description="队列名称列表,为空时统计所有队列")
12
12
  time_range: Optional[str] = Field(None, description="时间范围(如 '1h', '24h', '7d'),与 start_time/end_time 二选一")
13
- start_time: Optional[str] = Field(None, description="开始时间,与 time_range 二选一")
14
- end_time: Optional[str] = Field(None, description="结束时间,与 time_range 二选一")
13
+ start_time: Optional[str] = Field(None, description="开始时间(ISO格式),与 time_range 二选一")
14
+ end_time: Optional[str] = Field(None, description="结束时间(ISO格式),与 time_range 二选一")
15
15
  interval: Optional[str] = Field(default="1h", description="时间间隔")
16
+ queue_name: Optional[str] = Field(None, description="队列名称(可选)")
17
+
18
+ model_config = ConfigDict(json_schema_extra={
19
+ "examples": [
20
+ {
21
+ "time_range": "1h",
22
+ "queue_name": "email_queue"
23
+ },
24
+ {
25
+ "start_time": "2025-10-18T09:00:00Z",
26
+ "end_time": "2025-10-18T10:00:00Z",
27
+ "queues": ["email_queue", "sms_queue"],
28
+ "interval": "5m"
29
+ }
30
+ ]
31
+ })
16
32
 
17
33
 
18
34
  class QueueStatsResponse(BaseModel):