jettask 0.2.19__py3-none-any.whl → 0.2.20__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 (165) hide show
  1. jettask/__init__.py +10 -3
  2. jettask/cli.py +314 -228
  3. jettask/config/__init__.py +9 -1
  4. jettask/config/config.py +245 -0
  5. jettask/config/env_loader.py +381 -0
  6. jettask/config/lua_scripts.py +158 -0
  7. jettask/config/nacos_config.py +132 -5
  8. jettask/core/__init__.py +1 -1
  9. jettask/core/app.py +1573 -666
  10. jettask/core/app_importer.py +33 -16
  11. jettask/core/container.py +532 -0
  12. jettask/core/task.py +1 -4
  13. jettask/core/unified_manager_base.py +2 -2
  14. jettask/executor/__init__.py +38 -0
  15. jettask/executor/core.py +625 -0
  16. jettask/executor/executor.py +338 -0
  17. jettask/executor/orchestrator.py +290 -0
  18. jettask/executor/process_entry.py +638 -0
  19. jettask/executor/task_executor.py +317 -0
  20. jettask/messaging/__init__.py +68 -0
  21. jettask/messaging/event_pool.py +2188 -0
  22. jettask/messaging/reader.py +519 -0
  23. jettask/messaging/registry.py +266 -0
  24. jettask/messaging/scanner.py +369 -0
  25. jettask/messaging/sender.py +312 -0
  26. jettask/persistence/__init__.py +118 -0
  27. jettask/persistence/backlog_monitor.py +567 -0
  28. jettask/{backend/data_access.py → persistence/base.py} +58 -57
  29. jettask/persistence/consumer.py +315 -0
  30. jettask/{core → persistence}/db_manager.py +23 -22
  31. jettask/persistence/maintenance.py +81 -0
  32. jettask/persistence/message_consumer.py +259 -0
  33. jettask/{backend/namespace_data_access.py → persistence/namespace.py} +66 -98
  34. jettask/persistence/offline_recovery.py +196 -0
  35. jettask/persistence/queue_discovery.py +215 -0
  36. jettask/persistence/task_persistence.py +218 -0
  37. jettask/persistence/task_updater.py +583 -0
  38. jettask/scheduler/__init__.py +2 -2
  39. jettask/scheduler/loader.py +6 -5
  40. jettask/scheduler/run_scheduler.py +1 -1
  41. jettask/scheduler/scheduler.py +7 -7
  42. jettask/scheduler/{unified_scheduler_manager.py → scheduler_coordinator.py} +18 -13
  43. jettask/task/__init__.py +16 -0
  44. jettask/{router.py → task/router.py} +26 -8
  45. jettask/task/task_center/__init__.py +9 -0
  46. jettask/task/task_executor.py +318 -0
  47. jettask/task/task_registry.py +291 -0
  48. jettask/test_connection_monitor.py +73 -0
  49. jettask/utils/__init__.py +31 -1
  50. jettask/{monitor/run_backlog_collector.py → utils/backlog_collector.py} +1 -1
  51. jettask/utils/db_connector.py +1629 -0
  52. jettask/{db_init.py → utils/db_init.py} +1 -1
  53. jettask/utils/rate_limit/__init__.py +30 -0
  54. jettask/utils/rate_limit/concurrency_limiter.py +665 -0
  55. jettask/utils/rate_limit/config.py +145 -0
  56. jettask/utils/rate_limit/limiter.py +41 -0
  57. jettask/utils/rate_limit/manager.py +269 -0
  58. jettask/utils/rate_limit/qps_limiter.py +154 -0
  59. jettask/utils/rate_limit/task_limiter.py +384 -0
  60. jettask/utils/serializer.py +3 -0
  61. jettask/{monitor/stream_backlog_monitor.py → utils/stream_backlog.py} +14 -6
  62. jettask/utils/time_sync.py +173 -0
  63. jettask/webui/__init__.py +27 -0
  64. jettask/{api/v1 → webui/api}/alerts.py +1 -1
  65. jettask/{api/v1 → webui/api}/analytics.py +2 -2
  66. jettask/{api/v1 → webui/api}/namespaces.py +1 -1
  67. jettask/{api/v1 → webui/api}/overview.py +1 -1
  68. jettask/{api/v1 → webui/api}/queues.py +3 -3
  69. jettask/{api/v1 → webui/api}/scheduled.py +1 -1
  70. jettask/{api/v1 → webui/api}/settings.py +1 -1
  71. jettask/{api.py → webui/app.py} +253 -145
  72. jettask/webui/namespace_manager/__init__.py +10 -0
  73. jettask/{multi_namespace_consumer.py → webui/namespace_manager/multi.py} +69 -22
  74. jettask/{unified_consumer_manager.py → webui/namespace_manager/unified.py} +1 -1
  75. jettask/{run.py → webui/run.py} +2 -2
  76. jettask/{services → webui/services}/__init__.py +1 -3
  77. jettask/{services → webui/services}/overview_service.py +34 -16
  78. jettask/{services → webui/services}/queue_service.py +1 -1
  79. jettask/{backend → webui/services}/queue_stats_v2.py +1 -1
  80. jettask/{services → webui/services}/settings_service.py +1 -1
  81. jettask/worker/__init__.py +53 -0
  82. jettask/worker/lifecycle.py +1507 -0
  83. jettask/worker/manager.py +583 -0
  84. jettask/{core/offline_worker_recovery.py → worker/recovery.py} +268 -175
  85. {jettask-0.2.19.dist-info → jettask-0.2.20.dist-info}/METADATA +2 -71
  86. jettask-0.2.20.dist-info/RECORD +145 -0
  87. jettask/__main__.py +0 -140
  88. jettask/api/__init__.py +0 -103
  89. jettask/backend/__init__.py +0 -1
  90. jettask/backend/api/__init__.py +0 -3
  91. jettask/backend/api/v1/__init__.py +0 -17
  92. jettask/backend/api/v1/monitoring.py +0 -431
  93. jettask/backend/api/v1/namespaces.py +0 -504
  94. jettask/backend/api/v1/queues.py +0 -342
  95. jettask/backend/api/v1/tasks.py +0 -367
  96. jettask/backend/core/__init__.py +0 -3
  97. jettask/backend/core/cache.py +0 -221
  98. jettask/backend/core/database.py +0 -200
  99. jettask/backend/core/exceptions.py +0 -102
  100. jettask/backend/dependencies.py +0 -261
  101. jettask/backend/init_meta_db.py +0 -158
  102. jettask/backend/main.py +0 -1426
  103. jettask/backend/main_unified.py +0 -78
  104. jettask/backend/main_v2.py +0 -394
  105. jettask/backend/models/__init__.py +0 -3
  106. jettask/backend/models/requests.py +0 -236
  107. jettask/backend/models/responses.py +0 -230
  108. jettask/backend/namespace_api_old.py +0 -267
  109. jettask/backend/services/__init__.py +0 -3
  110. jettask/backend/start.py +0 -42
  111. jettask/backend/unified_api_router.py +0 -1541
  112. jettask/cleanup_deprecated_tables.sql +0 -16
  113. jettask/core/consumer_manager.py +0 -1695
  114. jettask/core/delay_scanner.py +0 -256
  115. jettask/core/event_pool.py +0 -1700
  116. jettask/core/heartbeat_process.py +0 -222
  117. jettask/core/task_batch.py +0 -153
  118. jettask/core/worker_scanner.py +0 -271
  119. jettask/executors/__init__.py +0 -5
  120. jettask/executors/asyncio.py +0 -876
  121. jettask/executors/base.py +0 -30
  122. jettask/executors/common.py +0 -148
  123. jettask/executors/multi_asyncio.py +0 -309
  124. jettask/gradio_app.py +0 -570
  125. jettask/integrated_gradio_app.py +0 -1088
  126. jettask/main.py +0 -0
  127. jettask/monitoring/__init__.py +0 -3
  128. jettask/pg_consumer.py +0 -1896
  129. jettask/run_monitor.py +0 -22
  130. jettask/run_webui.py +0 -148
  131. jettask/scheduler/multi_namespace_scheduler.py +0 -294
  132. jettask/scheduler/unified_manager.py +0 -450
  133. jettask/task_center_client.py +0 -150
  134. jettask/utils/serializer_optimized.py +0 -33
  135. jettask/webui_exceptions.py +0 -67
  136. jettask-0.2.19.dist-info/RECORD +0 -150
  137. /jettask/{constants.py → config/constants.py} +0 -0
  138. /jettask/{backend/config.py → config/task_center.py} +0 -0
  139. /jettask/{pg_consumer → messaging/pg_consumer}/pg_consumer_v2.py +0 -0
  140. /jettask/{pg_consumer → messaging/pg_consumer}/sql/add_execution_time_field.sql +0 -0
  141. /jettask/{pg_consumer → messaging/pg_consumer}/sql/create_new_tables.sql +0 -0
  142. /jettask/{pg_consumer → messaging/pg_consumer}/sql/create_tables_v3.sql +0 -0
  143. /jettask/{pg_consumer → messaging/pg_consumer}/sql/migrate_to_new_structure.sql +0 -0
  144. /jettask/{pg_consumer → messaging/pg_consumer}/sql/modify_time_fields.sql +0 -0
  145. /jettask/{pg_consumer → messaging/pg_consumer}/sql_utils.py +0 -0
  146. /jettask/{models.py → persistence/models.py} +0 -0
  147. /jettask/scheduler/{manager.py → task_crud.py} +0 -0
  148. /jettask/{schema.sql → schemas/schema.sql} +0 -0
  149. /jettask/{task_center.py → task/task_center/client.py} +0 -0
  150. /jettask/{monitoring → utils}/file_watcher.py +0 -0
  151. /jettask/{services/redis_monitor_service.py → utils/redis_monitor.py} +0 -0
  152. /jettask/{api/v1 → webui/api}/__init__.py +0 -0
  153. /jettask/{webui_config.py → webui/config.py} +0 -0
  154. /jettask/{webui_models → webui/models}/__init__.py +0 -0
  155. /jettask/{webui_models → webui/models}/namespace.py +0 -0
  156. /jettask/{services → webui/services}/alert_service.py +0 -0
  157. /jettask/{services → webui/services}/analytics_service.py +0 -0
  158. /jettask/{services → webui/services}/scheduled_task_service.py +0 -0
  159. /jettask/{services → webui/services}/task_service.py +0 -0
  160. /jettask/{webui_sql → webui/sql}/batch_upsert_functions.sql +0 -0
  161. /jettask/{webui_sql → webui/sql}/verify_database.sql +0 -0
  162. {jettask-0.2.19.dist-info → jettask-0.2.20.dist-info}/WHEEL +0 -0
  163. {jettask-0.2.19.dist-info → jettask-0.2.20.dist-info}/entry_points.txt +0 -0
  164. {jettask-0.2.19.dist-info → jettask-0.2.20.dist-info}/licenses/LICENSE +0 -0
  165. {jettask-0.2.19.dist-info → jettask-0.2.20.dist-info}/top_level.txt +0 -0
@@ -17,9 +17,9 @@ from datetime import datetime
17
17
  # 添加项目路径
18
18
  sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
19
19
 
20
- from jettask.pg_consumer import PostgreSQLConsumer
21
- from jettask.webui_config import PostgreSQLConfig, RedisConfig
22
- from jettask.core.consumer_manager import ConsumerStrategy
20
+ from jettask.persistence import PostgreSQLConsumer
21
+ from jettask.webui.config import PostgreSQLConfig, RedisConfig
22
+ # ConsumerStrategy 已移除,现在只使用 HEARTBEAT 策略
23
23
  from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
24
24
  from sqlalchemy.orm import sessionmaker
25
25
  from sqlalchemy import text
@@ -46,6 +46,7 @@ class NamespaceConsumerProcess:
46
46
  """
47
47
  self.namespace_info = namespace_info
48
48
  self.process: Optional[mp.Process] = None
49
+ self.shutdown_event = mp.Event() # 用于优雅退出的事件
49
50
 
50
51
  def start(self):
51
52
  """启动进程"""
@@ -65,12 +66,20 @@ class NamespaceConsumerProcess:
65
66
  """停止进程"""
66
67
  if self.process and self.process.is_alive():
67
68
  logger.info(f"停止命名空间 {self.namespace_info['name']} 的消费进程")
68
- self.process.terminate()
69
- self.process.join(timeout=10)
69
+ # 先发送优雅退出信号
70
+ self.shutdown_event.set()
71
+ # 等待进程正常退出(7秒:5秒清理超时 + 2秒缓冲)
72
+ self.process.join(timeout=7)
70
73
  if self.process.is_alive():
71
- logger.warning(f"强制停止命名空间 {self.namespace_info['name']} 的消费进程")
74
+ logger.warning(f"等待优雅退出超时(7秒),发送 SIGTERM 信号")
75
+ self.process.terminate()
76
+ self.process.join(timeout=3)
77
+ if self.process.is_alive():
78
+ logger.warning(f"SIGTERM 超时(3秒),强制 SIGKILL")
72
79
  self.process.kill()
73
- self.process.join()
80
+ self.process.join(timeout=2)
81
+ if self.process.is_alive():
82
+ logger.error(f"SIGKILL 后进程仍然存活,可能存在严重问题")
74
83
 
75
84
  def is_alive(self) -> bool:
76
85
  """检查进程是否存活"""
@@ -81,25 +90,42 @@ class NamespaceConsumerProcess:
81
90
  # 设置信号处理
82
91
  signal.signal(signal.SIGTERM, self._signal_handler)
83
92
  signal.signal(signal.SIGINT, self._signal_handler)
84
-
93
+
85
94
  # 创建新的事件循环
86
95
  loop = asyncio.new_event_loop()
87
96
  asyncio.set_event_loop(loop)
88
-
97
+
98
+ consumer = None
89
99
  try:
90
- loop.run_until_complete(self._async_run())
100
+ # 传递 consumer 引用以便在信号处理中使用
101
+ consumer = loop.run_until_complete(self._async_run())
91
102
  except KeyboardInterrupt:
92
103
  logger.info(f"命名空间 {self.namespace_info['name']} 的消费进程收到中断信号")
93
104
  except Exception as e:
94
105
  logger.error(f"命名空间 {self.namespace_info['name']} 的消费进程异常退出: {e}", exc_info=True)
95
106
  finally:
107
+ # 确保执行清理(带超时)
108
+ if consumer:
109
+ try:
110
+ logger.info(f"执行命名空间 {self.namespace_info['name']} 的消费者清理")
111
+ # 创建一个带超时的任务
112
+ async def cleanup_with_timeout():
113
+ try:
114
+ await asyncio.wait_for(consumer.stop(), timeout=5.0)
115
+ except asyncio.TimeoutError:
116
+ logger.warning(f"外层清理超时(5秒),强制退出")
117
+
118
+ loop.run_until_complete(cleanup_with_timeout())
119
+ except Exception as e:
120
+ logger.error(f"清理消费者时出错: {e}")
96
121
  loop.close()
97
122
 
98
123
  async def _async_run(self):
99
124
  """异步运行消费者"""
100
125
  namespace_name = self.namespace_info.get('name', 'unknown')
101
126
  logger.info(f"开始初始化命名空间 {namespace_name} 的消费者")
102
-
127
+
128
+ consumer = None
103
129
  try:
104
130
  # 创建配置
105
131
  pg_config_data = self.namespace_info.get('pg_config', {})
@@ -131,7 +157,8 @@ class NamespaceConsumerProcess:
131
157
  filtered_config = {k: v for k, v in redis_config_data.items() if k in valid_fields}
132
158
  redis_config = RedisConfig(**filtered_config)
133
159
 
134
-
160
+ print(f'{pg_config=}')
161
+ print(f'{redis_config=}')
135
162
  # 创建消费者实例
136
163
  consumer = PostgreSQLConsumer(
137
164
  pg_config=pg_config,
@@ -139,7 +166,7 @@ class NamespaceConsumerProcess:
139
166
  prefix=self.namespace_info.get('redis_prefix', 'jettask'),
140
167
  namespace_id=self.namespace_info.get('id'),
141
168
  namespace_name=self.namespace_info.get('name'),
142
- consumer_strategy=ConsumerStrategy.HEARTBEAT
169
+ # consumer_strategy 参数已移除,现在只使用 HEARTBEAT 策略
143
170
  )
144
171
 
145
172
  logger.info(f"命名空间 {namespace_name} 的消费者实例创建成功,准备启动")
@@ -147,25 +174,45 @@ class NamespaceConsumerProcess:
147
174
  # 启动消费者
148
175
  await consumer.start()
149
176
  logger.info(f"命名空间 {namespace_name} 的消费者已启动,进入运行状态")
150
-
177
+
151
178
  # 保持运行直到收到停止信号
152
179
  try:
153
- while True:
154
- await asyncio.sleep(10) # 每10秒检查一次
155
- # 可以在这里添加健康检查逻辑
180
+ while not self.shutdown_event.is_set():
181
+ await asyncio.sleep(1) # 每秒检查一次退出信号
156
182
  except asyncio.CancelledError:
157
183
  logger.info(f"命名空间 {namespace_name} 的消费者收到取消信号")
158
- await consumer.stop()
159
- raise
160
-
184
+ finally:
185
+ # 确保清理(带超时)
186
+ logger.info(f"命名空间 {namespace_name} 开始执行优雅退出")
187
+ try:
188
+ # 设置 5 秒超时,避免因网络问题导致清理卡住
189
+ await asyncio.wait_for(consumer.stop(), timeout=5.0)
190
+ logger.info(f"命名空间 {namespace_name} 清理完成")
191
+ except asyncio.TimeoutError:
192
+ logger.warning(f"命名空间 {namespace_name} 清理超时(5秒),强制退出")
193
+ except Exception as e:
194
+ logger.error(f"命名空间 {namespace_name} 清理失败: {e}")
195
+
161
196
  except Exception as e:
162
197
  logger.error(f"命名空间 {namespace_name} 的消费者启动失败: {e}", exc_info=True)
198
+ # 确保清理(带超时)
199
+ if consumer:
200
+ try:
201
+ await asyncio.wait_for(consumer.stop(), timeout=5.0)
202
+ except asyncio.TimeoutError:
203
+ logger.warning(f"清理失败的消费者超时,跳过")
204
+ except Exception as cleanup_error:
205
+ logger.error(f"清理失败的消费者时出错: {cleanup_error}")
163
206
  raise
207
+ finally:
208
+ # 返回 consumer 实例以便在外层 finally 中使用
209
+ return consumer
164
210
 
165
211
  def _signal_handler(self, signum, frame):
166
- """信号处理器"""
212
+ """信号处理器 - 触发优雅退出"""
167
213
  logger.info(f"命名空间 {self.namespace_info['name']} 的消费进程收到信号 {signum}")
168
- sys.exit(0)
214
+ # 设置退出事件,让主循环优雅退出
215
+ self.shutdown_event.set()
169
216
 
170
217
 
171
218
  class MultiNamespaceConsumerManager:
@@ -7,7 +7,7 @@ import logging
7
7
  import multiprocessing
8
8
  from typing import Dict, Optional, Set
9
9
  from jettask.core.unified_manager_base import UnifiedManagerBase
10
- from .multi_namespace_consumer import NamespaceConsumerProcess
10
+ from .multi import NamespaceConsumerProcess
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
 
@@ -11,7 +11,7 @@ import sys
11
11
  import os
12
12
  sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
13
13
 
14
- from jettask.api import app, monitor
14
+ from jettask.webui.app import app, monitor
15
15
  import uvicorn
16
16
 
17
17
  def main():
@@ -35,7 +35,7 @@ def main():
35
35
 
36
36
  # 运行服务器
37
37
  uvicorn.run(
38
- "jettask.webui.api:app",
38
+ "jettask.webui.app:app",
39
39
  host=args.host,
40
40
  port=args.port,
41
41
  log_level="info",
@@ -10,15 +10,13 @@ from .alert_service import AlertService
10
10
  from .analytics_service import AnalyticsService
11
11
  from .settings_service import SettingsService
12
12
  from .task_service import TaskService
13
- from .redis_monitor_service import RedisMonitorService
14
13
 
15
14
  __all__ = [
16
15
  'OverviewService',
17
- 'QueueService',
16
+ 'QueueService',
18
17
  'ScheduledTaskService',
19
18
  'AlertService',
20
19
  'AnalyticsService',
21
20
  'SettingsService',
22
21
  'TaskService',
23
- 'RedisMonitorService'
24
22
  ]
@@ -11,7 +11,7 @@ from sqlalchemy import text
11
11
  from sqlalchemy.ext.asyncio import AsyncSession
12
12
 
13
13
  from jettask.schemas import TimeRangeQuery
14
- from jettask.core.db_manager import get_db_manager
14
+ from jettask.persistence.db_manager import get_db_manager
15
15
 
16
16
  logger = logging.getLogger(__name__)
17
17
 
@@ -84,26 +84,44 @@ class OverviewService:
84
84
  'workers': 0
85
85
  }
86
86
 
87
+ # 使用注册管理器进行统计,避免 scan
88
+ from jettask.messaging.registry import QueueRegistry
89
+ from jettask.task.task_registry import TaskRegistry
90
+ from jettask.worker.manager import WorkerState as WorkerRegistry
91
+
92
+ queue_registry = QueueRegistry(
93
+ redis_client=None,
94
+ async_redis_client=redis_client,
95
+ redis_prefix=namespace
96
+ )
97
+
98
+ task_registry = TaskRegistry(
99
+ redis_client=None,
100
+ async_redis_client=redis_client,
101
+ redis_prefix=namespace
102
+ )
103
+
104
+ worker_registry = WorkerRegistry(
105
+ redis_client=None,
106
+ async_redis_client=redis_client,
107
+ redis_prefix=namespace
108
+ )
109
+
87
110
  # 统计队列数量
88
- queue_pattern = f"{namespace}:QUEUE:*"
89
- async for _ in redis_client.scan_iter(match=queue_pattern):
90
- stats['queues'] += 1
91
-
111
+ stats['queues'] = await queue_registry.get_queue_count()
112
+
92
113
  # 统计任务数量
93
- task_pattern = f"{namespace}:TASK:*"
94
- async for _ in redis_client.scan_iter(match=task_pattern):
95
- stats['tasks'] += 1
96
-
114
+ stats['tasks'] = await task_registry.get_task_count_from_redis()
115
+
97
116
  # 统计延迟任务数量
98
- delayed_pattern = f"{namespace}:DELAYED_QUEUE:*"
99
- async for key in redis_client.scan_iter(match=delayed_pattern):
100
- count = await redis_client.zcard(key)
117
+ delayed_queues = await queue_registry.get_all_delayed_queues()
118
+ for queue in delayed_queues:
119
+ delayed_key = f"{namespace}:DELAYED_QUEUE:{queue}"
120
+ count = await redis_client.zcard(delayed_key)
101
121
  stats['delayed_tasks'] += count
102
-
122
+
103
123
  # 统计工作进程数量
104
- worker_pattern = f"{namespace}:WORKER:*"
105
- async for _ in redis_client.scan_iter(match=worker_pattern):
106
- stats['workers'] += 1
124
+ stats['workers'] = await worker_registry.get_worker_count()
107
125
 
108
126
  return stats
109
127
 
@@ -226,7 +226,7 @@ class QueueService:
226
226
 
227
227
  try:
228
228
  # 导入 QueueStatsV2
229
- from jettask.backend.queue_stats_v2 import QueueStatsV2
229
+ from jettask.webui.services.queue_stats_v2 import QueueStatsV2
230
230
 
231
231
  # 创建统计服务实例
232
232
  stats_service = QueueStatsV2(
@@ -9,7 +9,7 @@ from collections import defaultdict
9
9
  import redis.asyncio as redis
10
10
  from sqlalchemy import text
11
11
  from sqlalchemy.ext.asyncio import AsyncSession
12
- from jettask.constants import is_internal_consumer
12
+ from jettask.config.constants import is_internal_consumer
13
13
 
14
14
  logger = logging.getLogger(__name__)
15
15
 
@@ -9,7 +9,7 @@ from datetime import datetime
9
9
  from sqlalchemy import text
10
10
  from urllib.parse import urlparse
11
11
 
12
- from jettask.core.db_manager import get_db_manager
12
+ from jettask.persistence.db_manager import get_db_manager
13
13
  from jettask.schemas import (
14
14
  ConfigMode,
15
15
  NamespaceCreate,
@@ -0,0 +1,53 @@
1
+ """
2
+ Worker 管理模块
3
+
4
+ 提供 Worker 的创建、生命周期管理、状态监控等功能。
5
+
6
+ 推荐使用新接口:
7
+ from jettask.worker import WorkerManager
8
+
9
+ manager = WorkerManager(redis, async_redis, 'jettask')
10
+ worker_id = await manager.start_worker('MyApp', ['queue1'])
11
+ """
12
+
13
+ # 主要接口
14
+ from .manager import (
15
+ WorkerManager,
16
+ WorkerState, # Worker 状态管理(之前叫 WorkerRegistry)
17
+ ConsumerManager,
18
+ WorkerNaming,
19
+ )
20
+
21
+ # 生命周期和状态管理
22
+ from .lifecycle import (
23
+ WorkerLifecycle,
24
+ WorkerStateManager,
25
+ HeartbeatThreadManager,
26
+ WorkerScanner,
27
+ HeartbeatConsumerStrategy, # 兼容性
28
+ )
29
+
30
+ # 恢复
31
+ from .recovery import OfflineWorkerRecovery
32
+
33
+ # 兼容性别名:WorkerRegistry -> WorkerState
34
+ WorkerRegistry = WorkerState
35
+
36
+ __all__ = [
37
+ # 主要接口
38
+ 'WorkerManager',
39
+ 'WorkerState', # 新名称(推荐使用)
40
+ 'WorkerRegistry', # 兼容性别名
41
+ 'ConsumerManager',
42
+ 'WorkerNaming',
43
+
44
+ # 生命周期和状态管理
45
+ 'WorkerLifecycle',
46
+ 'WorkerStateManager',
47
+ 'HeartbeatThreadManager',
48
+ 'WorkerScanner',
49
+ 'HeartbeatConsumerStrategy', # 兼容性
50
+
51
+ # 恢复
52
+ 'OfflineWorkerRecovery',
53
+ ]