celestialflow 3.2.0__tar.gz → 3.2.2__tar.gz
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.
- {celestialflow-3.2.0 → celestialflow-3.2.2}/PKG-INFO +31 -32
- {celestialflow-3.2.0 → celestialflow-3.2.2}/README.md +29 -30
- {celestialflow-3.2.0 → celestialflow-3.2.2}/pyproject.toml +40 -5
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/__init__.py +21 -16
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/funnel/__init__.py +2 -2
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/funnel/core_inlet.py +22 -22
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/funnel/core_spout.py +17 -5
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/graph/__init__.py +4 -4
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/graph/core_graph.py +162 -270
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/graph/core_structure.py +54 -42
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/graph/util_analysis.py +24 -24
- celestialflow-3.2.2/src/celestialflow/graph/util_serialize.py +153 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/observability/__init__.py +6 -1
- celestialflow-3.2.2/src/celestialflow/observability/core_observer.py +67 -0
- celestialflow-3.2.2/src/celestialflow/observability/core_progress.py +61 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/observability/core_report.py +31 -74
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/persistence/__init__.py +2 -2
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/persistence/core_fail.py +46 -26
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/persistence/core_log.py +250 -83
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/persistence/core_success.py +2 -2
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/persistence/util_jsonl.py +68 -25
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/__init__.py +2 -2
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/core_dispatch.py +46 -47
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/core_envelope.py +19 -8
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/core_metrics.py +17 -11
- celestialflow-3.2.2/src/celestialflow/runtime/core_queue.py +253 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/util_errors.py +122 -8
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/util_estimators.py +3 -3
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/util_hash.py +1 -1
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/runtime/util_types.py +85 -17
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/stage/__init__.py +4 -4
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/stage/core_executor.py +193 -172
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/stage/core_stage.py +53 -62
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/stage/core_stages.py +101 -53
- celestialflow-3.2.2/src/celestialflow/utils/__init__.py +5 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/utils/util_benchmark.py +5 -3
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/utils/util_clone.py +14 -13
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/utils/util_format.py +7 -7
- celestialflow-3.2.2/src/celestialflow/web/__init__.py +11 -0
- celestialflow-3.2.2/src/celestialflow/web/config.json +23 -0
- celestialflow-3.2.2/src/celestialflow/web/core_server.py +217 -0
- celestialflow-3.2.2/src/celestialflow/web/routes/__init__.py +33 -0
- celestialflow-3.2.2/src/celestialflow/web/routes/pull_routes.py +139 -0
- celestialflow-3.2.2/src/celestialflow/web/routes/push_routes.py +167 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/web/static/css/_colors.css +136 -135
- celestialflow-3.2.2/src/celestialflow/web/static/css/base.css +854 -0
- celestialflow-3.2.2/src/celestialflow/web/static/css/dashboard.css +71 -0
- celestialflow-3.2.2/src/celestialflow/web/static/css/dashboard_analysis.css +39 -0
- celestialflow-3.2.2/src/celestialflow/web/static/css/dashboard_history.css +87 -0
- celestialflow-3.2.2/src/celestialflow/web/static/css/dashboard_statuses.css +238 -0
- celestialflow-3.2.2/src/celestialflow/web/static/css/dashboard_structure.css +25 -0
- celestialflow-3.2.2/src/celestialflow/web/static/css/dashboard_summary.css +134 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/web/static/css/errors.css +30 -1
- celestialflow-3.2.0/src/celestialflow/web/static/css/inject.css → celestialflow-3.2.2/src/celestialflow/web/static/css/injection.css +57 -4
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_analysis.js → celestialflow-3.2.2/src/celestialflow/web/static/js/dashboard_analysis.js +16 -10
- celestialflow-3.2.2/src/celestialflow/web/static/js/dashboard_history.js +367 -0
- celestialflow-3.2.2/src/celestialflow/web/static/js/dashboard_statuses.js +235 -0
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_structure.js → celestialflow-3.2.2/src/celestialflow/web/static/js/dashboard_structure.js +69 -40
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_summary.js → celestialflow-3.2.2/src/celestialflow/web/static/js/dashboard_summary.js +15 -23
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_errors.js → celestialflow-3.2.2/src/celestialflow/web/static/js/errors.js +43 -16
- celestialflow-3.2.2/src/celestialflow/web/static/js/i18n.js +389 -0
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_injection.js → celestialflow-3.2.2/src/celestialflow/web/static/js/injection.js +98 -32
- celestialflow-3.2.2/src/celestialflow/web/static/js/layout_editor.js +164 -0
- celestialflow-3.2.2/src/celestialflow/web/static/js/main.js +291 -0
- celestialflow-3.2.2/src/celestialflow/web/static/js/utils.js +117 -0
- celestialflow-3.2.2/src/celestialflow/web/static/js/web_config.js +305 -0
- celestialflow-3.2.0/src/celestialflow/web/static/ts/task_analysis.ts → celestialflow-3.2.2/src/celestialflow/web/static/ts/dashboard_analysis.ts +17 -15
- celestialflow-3.2.2/src/celestialflow/web/static/ts/dashboard_history.ts +455 -0
- celestialflow-3.2.2/src/celestialflow/web/static/ts/dashboard_statuses.ts +331 -0
- celestialflow-3.2.0/src/celestialflow/web/static/ts/task_structure.ts → celestialflow-3.2.2/src/celestialflow/web/static/ts/dashboard_structure.ts +90 -45
- celestialflow-3.2.0/src/celestialflow/web/static/ts/task_summary.ts → celestialflow-3.2.2/src/celestialflow/web/static/ts/dashboard_summary.ts +16 -28
- celestialflow-3.2.0/src/celestialflow/web/static/ts/task_errors.ts → celestialflow-3.2.2/src/celestialflow/web/static/ts/errors.ts +62 -19
- celestialflow-3.2.2/src/celestialflow/web/static/ts/globals.d.ts +27 -0
- celestialflow-3.2.2/src/celestialflow/web/static/ts/i18n.ts +406 -0
- celestialflow-3.2.0/src/celestialflow/web/static/ts/task_injection.ts → celestialflow-3.2.2/src/celestialflow/web/static/ts/injection.ts +108 -38
- celestialflow-3.2.2/src/celestialflow/web/static/ts/layout_editor.ts +190 -0
- celestialflow-3.2.2/src/celestialflow/web/static/ts/main.ts +329 -0
- celestialflow-3.2.2/src/celestialflow/web/static/ts/utils.ts +132 -0
- celestialflow-3.2.2/src/celestialflow/web/static/ts/web_config.ts +357 -0
- celestialflow-3.2.2/src/celestialflow/web/templates/index.html +732 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/web/util_config.py +6 -3
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/web/util_error.py +23 -8
- celestialflow-3.2.2/src/celestialflow/web/util_models.py +72 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow.egg-info/PKG-INFO +31 -32
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow.egg-info/SOURCES.txt +29 -28
- celestialflow-3.2.0/src/celestialflow/graph/util_serialize.py +0 -152
- celestialflow-3.2.0/src/celestialflow/observability/core_observer.py +0 -29
- celestialflow-3.2.0/src/celestialflow/observability/core_progress.py +0 -30
- celestialflow-3.2.0/src/celestialflow/runtime/core_queue.py +0 -283
- celestialflow-3.2.0/src/celestialflow/runtime/util_factories.py +0 -48
- celestialflow-3.2.0/src/celestialflow/utils/__init__.py +0 -1
- celestialflow-3.2.0/src/celestialflow/web/__init__.py +0 -6
- celestialflow-3.2.0/src/celestialflow/web/config.json +0 -35
- celestialflow-3.2.0/src/celestialflow/web/core_server.py +0 -530
- celestialflow-3.2.0/src/celestialflow/web/static/css/base.css +0 -427
- celestialflow-3.2.0/src/celestialflow/web/static/css/dashboard.css +0 -348
- celestialflow-3.2.0/src/celestialflow/web/static/js/main.js +0 -115
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_config.js +0 -124
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_history.js +0 -139
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_statuses.js +0 -130
- celestialflow-3.2.0/src/celestialflow/web/static/js/task_topology.js +0 -59
- celestialflow-3.2.0/src/celestialflow/web/static/js/utils.js +0 -269
- celestialflow-3.2.0/src/celestialflow/web/static/js/web_config.js +0 -129
- celestialflow-3.2.0/src/celestialflow/web/static/ts/globals.d.ts +0 -6
- celestialflow-3.2.0/src/celestialflow/web/static/ts/main.ts +0 -133
- celestialflow-3.2.0/src/celestialflow/web/static/ts/task_history.ts +0 -159
- celestialflow-3.2.0/src/celestialflow/web/static/ts/task_statuses.ts +0 -178
- celestialflow-3.2.0/src/celestialflow/web/static/ts/utils.ts +0 -314
- celestialflow-3.2.0/src/celestialflow/web/static/ts/web_config.ts +0 -155
- celestialflow-3.2.0/src/celestialflow/web/templates/index.html +0 -417
- celestialflow-3.2.0/tests/test_analysis.py +0 -132
- celestialflow-3.2.0/tests/test_envelope.py +0 -71
- celestialflow-3.2.0/tests/test_executor.py +0 -369
- celestialflow-3.2.0/tests/test_graph.py +0 -674
- celestialflow-3.2.0/tests/test_metrics.py +0 -119
- celestialflow-3.2.0/tests/test_queue.py +0 -149
- celestialflow-3.2.0/tests/test_stage.py +0 -91
- celestialflow-3.2.0/tests/test_structure.py +0 -85
- celestialflow-3.2.0/tests/test_utils.py +0 -234
- {celestialflow-3.2.0 → celestialflow-3.2.2}/setup.cfg +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/persistence/util_constant.py +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/utils/util_collections.py +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/web/static/favicon.ico +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow/web/util_cal.py +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow.egg-info/dependency_links.txt +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow.egg-info/entry_points.txt +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow.egg-info/requires.txt +0 -0
- {celestialflow-3.2.0 → celestialflow-3.2.2}/src/celestialflow.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: celestialflow
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.2
|
|
4
4
|
Summary: A flexible GRAPH-based task orchestration framework.
|
|
5
5
|
Author-email: Mr-xiaotian <mingxiaomingtian@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -12,7 +12,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Framework :: FastAPI
|
|
14
14
|
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
-
Requires-Python: >=3.
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
Requires-Dist: tqdm
|
|
18
18
|
Requires-Dist: fastapi
|
|
@@ -44,7 +44,7 @@ Requires-Dist: celestialtree>=0.1.2
|
|
|
44
44
|
</p>
|
|
45
45
|
|
|
46
46
|
<p align="center">
|
|
47
|
-
<a href="README.md">中文</a> | <a href="docs/en/README.md">English</a> | <a href="docs/ja/README.md">日本語</a>
|
|
47
|
+
<a href="https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/README.md">中文</a> | <a href="https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/en/README.md">English</a> | <a href="https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/ja/README.md">日本語</a>
|
|
48
48
|
</p>
|
|
49
49
|
|
|
50
50
|
**CelestialFlow** 是一个轻量级但功能完全的任务流框架,适合需要 **复杂依赖关系**、**灵活执行模型**、**跨设备运行**与**实时可视化监控** 的中/大型 Python 任务系统。
|
|
@@ -64,11 +64,10 @@ TaskExecutor 实现了对任务的结果缓存,任务去重,进度条显示
|
|
|
64
64
|
|
|
65
65
|
TaskStage 的任务执行模式同样包含三种,与TaskExecutor中一致。
|
|
66
66
|
|
|
67
|
-
在图级别上,每个 Stage
|
|
67
|
+
在图级别上,每个 Stage 支持两种上下文模式:
|
|
68
68
|
|
|
69
69
|
* **线性执行(serial layout)**:当前节点执行完毕再启动下一节点(下游节点可提前接收任务但不会立即执行)。
|
|
70
70
|
* **线程执行(thread layout)**:当前节点在主进程的独立线程中启动,适合 I/O 密集型任务和不可 pickle 的函数(如 lambda)。
|
|
71
|
-
* **并行执行(process layout)**:当前节点启动后立刻前去启动下一节点。
|
|
72
71
|
|
|
73
72
|
TaskGraph 能构建完整的 **有向图结构(Directed Graph)**,不仅支持传统的有向无环图(DAG),也能灵活表达 **树形(Tree)**、**环形(loop)** 乃至于 **完全图(Complete Graph)** 形式的任务依赖。
|
|
74
73
|
|
|
@@ -150,8 +149,8 @@ def square(x):
|
|
|
150
149
|
|
|
151
150
|
if __name__ == "__main__":
|
|
152
151
|
# 定义两个任务节点
|
|
153
|
-
stage1 = TaskStage(name="Adder", func=add, execution_mode="thread", unpack_task_args=True
|
|
154
|
-
stage2 = TaskStage(name="Squarer"func=square,
|
|
152
|
+
stage1 = TaskStage(name="Adder", func=add, stage_mode="thread", execution_mode="thread", unpack_task_args=True)
|
|
153
|
+
stage2 = TaskStage(name="Squarer", func=square, stage_mode="thread", execution_mode="thread")
|
|
155
154
|
|
|
156
155
|
# 构建任务图结构
|
|
157
156
|
graph = TaskGraph()
|
|
@@ -159,7 +158,7 @@ if __name__ == "__main__":
|
|
|
159
158
|
graph.connect([stage1], [stage2])
|
|
160
159
|
|
|
161
160
|
# 初始化任务并启动
|
|
162
|
-
graph.start_graph({stage1.
|
|
161
|
+
graph.start_graph({stage1.get_name(): [(1, 2), (3, 4), (5, 6)]})
|
|
163
162
|
```
|
|
164
163
|
|
|
165
164
|
注意不要在.ipynb中运行。
|
|
@@ -213,7 +212,7 @@ flowchart TD
|
|
|
213
212
|
|
|
214
213
|
以下三篇可以作为补充阅读:
|
|
215
214
|
|
|
216
|
-
- [runtime/
|
|
215
|
+
- [runtime/util_hash.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/util_hash.md)
|
|
217
216
|
- [runtime/util_types.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/util_types.md)
|
|
218
217
|
- [runtime/util_errors.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/util_errors.md)
|
|
219
218
|
- [persistence/core_fail.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/persistence/core_fail.md)
|
|
@@ -229,24 +228,24 @@ flowchart TD
|
|
|
229
228
|
|
|
230
229
|
你可以继续运行更多的演示代码,这里记录了各个演示文件与其中的演示函数说明:
|
|
231
230
|
|
|
232
|
-
[🎮demo/](https://github.com/Mr-xiaotian/CelestialFlow/
|
|
231
|
+
[🎮demo/](https://github.com/Mr-xiaotian/CelestialFlow/tree/main/docs/zh-CN/demo)
|
|
233
232
|
|
|
234
233
|
如果你想运行测试代码, 可以先查看如下文档内容:
|
|
235
234
|
|
|
236
|
-
[🧪tests/](https://github.com/Mr-xiaotian/CelestialFlow/
|
|
235
|
+
[🧪tests/](https://github.com/Mr-xiaotian/CelestialFlow/tree/main/docs/zh-CN/tests)
|
|
237
236
|
|
|
238
237
|
如果你想查看bench内容, 这里的数据成为框架中部分设计的决策依据:
|
|
239
238
|
|
|
240
|
-
[⚡bench/](https://github.com/Mr-xiaotian/CelestialFlow/
|
|
239
|
+
[⚡bench/](https://github.com/Mr-xiaotian/CelestialFlow/tree/main/docs/zh-CN/bench)
|
|
241
240
|
|
|
242
241
|
## 环境要求(Requirements)
|
|
243
242
|
|
|
244
|
-
**CelestialFlow** 基于 Python 3.
|
|
243
|
+
**CelestialFlow** 基于 Python 3.11+,并依赖以下核心组件。
|
|
245
244
|
请确保你的环境能够正常安装这些依赖(`pip install celestialflow` 会自动安装)。
|
|
246
245
|
|
|
247
246
|
| 依赖包 | 说明 |
|
|
248
247
|
| ----------------- | ---- |
|
|
249
|
-
| **Python ≥ 3.
|
|
248
|
+
| **Python ≥ 3.11** | 运行环境,建议使用 3.11 及以上版本 |
|
|
250
249
|
| **fastapi** | Web 服务接口框架(用于任务可视化与远程控制) |
|
|
251
250
|
| **uvicorn** | FastAPI 的高性能 ASGI 服务器 |
|
|
252
251
|
| **requests** | HTTP 客户端库,用于任务状态上报与远程调用 |
|
|
@@ -261,35 +260,35 @@ flowchart TD
|
|
|
261
260
|
<p align="center">
|
|
262
261
|
<img src="https://raw.githubusercontent.com/Mr-xiaotian/CelestialFlow/main/img/file_structure.svg" alt="FileStructure" />
|
|
263
262
|
<br/>
|
|
264
|
-
<em>celestial-flow 3.2.
|
|
263
|
+
<em>celestial-flow 3.2.2</em>
|
|
265
264
|
</p>
|
|
266
265
|
|
|
267
266
|
(该视图由我的另一个项目[CelestialVault](https://github.com/Mr-xiaotian/CelestialVault)中inst_file.FileTree.print_tree()生成。转换为图片则借助[Carbon](https://carbon.now.sh)。)
|
|
268
267
|
|
|
269
268
|
## 版本日志(Version Log)
|
|
270
|
-
- 3.2.
|
|
269
|
+
- 3.2.2
|
|
271
270
|
- feat:
|
|
272
|
-
-
|
|
273
|
-
|
|
274
|
-
-
|
|
275
|
-
- 重补了不少图论课
|
|
276
|
-
- 将graph/stage/executor的默认log level从`SUCCESS`改为`INFO`, 也就是默认只显示开启关闭信息与错误
|
|
277
|
-
- 在web页面中添加配置按钮
|
|
278
|
-
- 当前仅支持设置刷新间隔与历史长度, 之后可以进行更多设置
|
|
271
|
+
- `core_server` 中添加数据锁, 避免并发访问导致的错误状态
|
|
272
|
+
- 优化前端设置面板的显示, 现在只显示全局设置与当前页相关设置
|
|
273
|
+
- 在设置面板中添加全局设置中的 "是否自动更新" 选项与错误日志页面中的 "排序方式" 两项
|
|
279
274
|
- refactor:
|
|
280
|
-
-
|
|
281
|
-
|
|
282
|
-
- 尚未进行严格的bench测试, 但应该会带来一定的性能优化
|
|
283
|
-
- 重构networkx图的建立过程, 现在直接通过节点与出边进行建立, 不再依赖递归
|
|
284
|
-
- 在重试检测机制中计算bytes类型的hash, 而非原本的string类型
|
|
285
|
-
- 根据 bench_hash_memory, 节省内存约23%
|
|
286
|
-
- 将节点状态中的deltas数据放在web端由js计算, 减少不必要的通信数据
|
|
275
|
+
- 删除前后端通讯中的 `summary` , 节点的总体预期结束时间由各个节点的 `status` 分别传递, 并由前端计算整体的预期结束时间
|
|
276
|
+
- 修改 `structure_graph`(原 `structure_json`) 字段的内容, 现在更为简洁, 避免信息冗余, 同时方便后续拓展
|
|
287
277
|
- fix:
|
|
288
|
-
-
|
|
278
|
+
- 修复指标折线图中指标选择失效的问题
|
|
279
|
+
- 修改 `report.stop` 中_refresh_all的执行顺序, 避免与thread中的刷新冲突
|
|
280
|
+
- 在 `graph._finalize_nodes` 中添加对thread未终止的防御性检查
|
|
281
|
+
- 修复 `stage` 中 `start_time` 在未定义前被 `report` 调用的问题
|
|
282
|
+
- 修复 `TaskRedisTransport._transport` 中使用 `id()` 来计算task_id导致的问题
|
|
283
|
+
- 修复部分任务无法被hash导致的panic问题
|
|
284
|
+
- chore:
|
|
285
|
+
- 删除所有的 `type: ignore`
|
|
286
|
+
- 好看不少
|
|
287
|
+
- 在 `start_*` 函数的doc-string中标注该函数为一次性调用函数
|
|
289
288
|
|
|
290
289
|
更多过往日志可看:
|
|
291
290
|
|
|
292
|
-
[change_log.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/
|
|
291
|
+
[change_log.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/change_log.md )
|
|
293
292
|
|
|
294
293
|
## Star 历史趋势(Star History)
|
|
295
294
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
21
|
<p align="center">
|
|
22
|
-
<a href="README.md">中文</a> | <a href="docs/en/README.md">English</a> | <a href="docs/ja/README.md">日本語</a>
|
|
22
|
+
<a href="https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/README.md">中文</a> | <a href="https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/en/README.md">English</a> | <a href="https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/ja/README.md">日本語</a>
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
**CelestialFlow** 是一个轻量级但功能完全的任务流框架,适合需要 **复杂依赖关系**、**灵活执行模型**、**跨设备运行**与**实时可视化监控** 的中/大型 Python 任务系统。
|
|
@@ -39,11 +39,10 @@ TaskExecutor 实现了对任务的结果缓存,任务去重,进度条显示
|
|
|
39
39
|
|
|
40
40
|
TaskStage 的任务执行模式同样包含三种,与TaskExecutor中一致。
|
|
41
41
|
|
|
42
|
-
在图级别上,每个 Stage
|
|
42
|
+
在图级别上,每个 Stage 支持两种上下文模式:
|
|
43
43
|
|
|
44
44
|
* **线性执行(serial layout)**:当前节点执行完毕再启动下一节点(下游节点可提前接收任务但不会立即执行)。
|
|
45
45
|
* **线程执行(thread layout)**:当前节点在主进程的独立线程中启动,适合 I/O 密集型任务和不可 pickle 的函数(如 lambda)。
|
|
46
|
-
* **并行执行(process layout)**:当前节点启动后立刻前去启动下一节点。
|
|
47
46
|
|
|
48
47
|
TaskGraph 能构建完整的 **有向图结构(Directed Graph)**,不仅支持传统的有向无环图(DAG),也能灵活表达 **树形(Tree)**、**环形(loop)** 乃至于 **完全图(Complete Graph)** 形式的任务依赖。
|
|
49
48
|
|
|
@@ -125,8 +124,8 @@ def square(x):
|
|
|
125
124
|
|
|
126
125
|
if __name__ == "__main__":
|
|
127
126
|
# 定义两个任务节点
|
|
128
|
-
stage1 = TaskStage(name="Adder", func=add, execution_mode="thread", unpack_task_args=True
|
|
129
|
-
stage2 = TaskStage(name="Squarer"func=square,
|
|
127
|
+
stage1 = TaskStage(name="Adder", func=add, stage_mode="thread", execution_mode="thread", unpack_task_args=True)
|
|
128
|
+
stage2 = TaskStage(name="Squarer", func=square, stage_mode="thread", execution_mode="thread")
|
|
130
129
|
|
|
131
130
|
# 构建任务图结构
|
|
132
131
|
graph = TaskGraph()
|
|
@@ -134,7 +133,7 @@ if __name__ == "__main__":
|
|
|
134
133
|
graph.connect([stage1], [stage2])
|
|
135
134
|
|
|
136
135
|
# 初始化任务并启动
|
|
137
|
-
graph.start_graph({stage1.
|
|
136
|
+
graph.start_graph({stage1.get_name(): [(1, 2), (3, 4), (5, 6)]})
|
|
138
137
|
```
|
|
139
138
|
|
|
140
139
|
注意不要在.ipynb中运行。
|
|
@@ -188,7 +187,7 @@ flowchart TD
|
|
|
188
187
|
|
|
189
188
|
以下三篇可以作为补充阅读:
|
|
190
189
|
|
|
191
|
-
- [runtime/
|
|
190
|
+
- [runtime/util_hash.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/util_hash.md)
|
|
192
191
|
- [runtime/util_types.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/util_types.md)
|
|
193
192
|
- [runtime/util_errors.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/util_errors.md)
|
|
194
193
|
- [persistence/core_fail.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/persistence/core_fail.md)
|
|
@@ -204,24 +203,24 @@ flowchart TD
|
|
|
204
203
|
|
|
205
204
|
你可以继续运行更多的演示代码,这里记录了各个演示文件与其中的演示函数说明:
|
|
206
205
|
|
|
207
|
-
[🎮demo/](https://github.com/Mr-xiaotian/CelestialFlow/
|
|
206
|
+
[🎮demo/](https://github.com/Mr-xiaotian/CelestialFlow/tree/main/docs/zh-CN/demo)
|
|
208
207
|
|
|
209
208
|
如果你想运行测试代码, 可以先查看如下文档内容:
|
|
210
209
|
|
|
211
|
-
[🧪tests/](https://github.com/Mr-xiaotian/CelestialFlow/
|
|
210
|
+
[🧪tests/](https://github.com/Mr-xiaotian/CelestialFlow/tree/main/docs/zh-CN/tests)
|
|
212
211
|
|
|
213
212
|
如果你想查看bench内容, 这里的数据成为框架中部分设计的决策依据:
|
|
214
213
|
|
|
215
|
-
[⚡bench/](https://github.com/Mr-xiaotian/CelestialFlow/
|
|
214
|
+
[⚡bench/](https://github.com/Mr-xiaotian/CelestialFlow/tree/main/docs/zh-CN/bench)
|
|
216
215
|
|
|
217
216
|
## 环境要求(Requirements)
|
|
218
217
|
|
|
219
|
-
**CelestialFlow** 基于 Python 3.
|
|
218
|
+
**CelestialFlow** 基于 Python 3.11+,并依赖以下核心组件。
|
|
220
219
|
请确保你的环境能够正常安装这些依赖(`pip install celestialflow` 会自动安装)。
|
|
221
220
|
|
|
222
221
|
| 依赖包 | 说明 |
|
|
223
222
|
| ----------------- | ---- |
|
|
224
|
-
| **Python ≥ 3.
|
|
223
|
+
| **Python ≥ 3.11** | 运行环境,建议使用 3.11 及以上版本 |
|
|
225
224
|
| **fastapi** | Web 服务接口框架(用于任务可视化与远程控制) |
|
|
226
225
|
| **uvicorn** | FastAPI 的高性能 ASGI 服务器 |
|
|
227
226
|
| **requests** | HTTP 客户端库,用于任务状态上报与远程调用 |
|
|
@@ -236,35 +235,35 @@ flowchart TD
|
|
|
236
235
|
<p align="center">
|
|
237
236
|
<img src="https://raw.githubusercontent.com/Mr-xiaotian/CelestialFlow/main/img/file_structure.svg" alt="FileStructure" />
|
|
238
237
|
<br/>
|
|
239
|
-
<em>celestial-flow 3.2.
|
|
238
|
+
<em>celestial-flow 3.2.2</em>
|
|
240
239
|
</p>
|
|
241
240
|
|
|
242
241
|
(该视图由我的另一个项目[CelestialVault](https://github.com/Mr-xiaotian/CelestialVault)中inst_file.FileTree.print_tree()生成。转换为图片则借助[Carbon](https://carbon.now.sh)。)
|
|
243
242
|
|
|
244
243
|
## 版本日志(Version Log)
|
|
245
|
-
- 3.2.
|
|
244
|
+
- 3.2.2
|
|
246
245
|
- feat:
|
|
247
|
-
-
|
|
248
|
-
|
|
249
|
-
-
|
|
250
|
-
- 重补了不少图论课
|
|
251
|
-
- 将graph/stage/executor的默认log level从`SUCCESS`改为`INFO`, 也就是默认只显示开启关闭信息与错误
|
|
252
|
-
- 在web页面中添加配置按钮
|
|
253
|
-
- 当前仅支持设置刷新间隔与历史长度, 之后可以进行更多设置
|
|
246
|
+
- `core_server` 中添加数据锁, 避免并发访问导致的错误状态
|
|
247
|
+
- 优化前端设置面板的显示, 现在只显示全局设置与当前页相关设置
|
|
248
|
+
- 在设置面板中添加全局设置中的 "是否自动更新" 选项与错误日志页面中的 "排序方式" 两项
|
|
254
249
|
- refactor:
|
|
255
|
-
-
|
|
256
|
-
|
|
257
|
-
- 尚未进行严格的bench测试, 但应该会带来一定的性能优化
|
|
258
|
-
- 重构networkx图的建立过程, 现在直接通过节点与出边进行建立, 不再依赖递归
|
|
259
|
-
- 在重试检测机制中计算bytes类型的hash, 而非原本的string类型
|
|
260
|
-
- 根据 bench_hash_memory, 节省内存约23%
|
|
261
|
-
- 将节点状态中的deltas数据放在web端由js计算, 减少不必要的通信数据
|
|
250
|
+
- 删除前后端通讯中的 `summary` , 节点的总体预期结束时间由各个节点的 `status` 分别传递, 并由前端计算整体的预期结束时间
|
|
251
|
+
- 修改 `structure_graph`(原 `structure_json`) 字段的内容, 现在更为简洁, 避免信息冗余, 同时方便后续拓展
|
|
262
252
|
- fix:
|
|
263
|
-
-
|
|
253
|
+
- 修复指标折线图中指标选择失效的问题
|
|
254
|
+
- 修改 `report.stop` 中_refresh_all的执行顺序, 避免与thread中的刷新冲突
|
|
255
|
+
- 在 `graph._finalize_nodes` 中添加对thread未终止的防御性检查
|
|
256
|
+
- 修复 `stage` 中 `start_time` 在未定义前被 `report` 调用的问题
|
|
257
|
+
- 修复 `TaskRedisTransport._transport` 中使用 `id()` 来计算task_id导致的问题
|
|
258
|
+
- 修复部分任务无法被hash导致的panic问题
|
|
259
|
+
- chore:
|
|
260
|
+
- 删除所有的 `type: ignore`
|
|
261
|
+
- 好看不少
|
|
262
|
+
- 在 `start_*` 函数的doc-string中标注该函数为一次性调用函数
|
|
264
263
|
|
|
265
264
|
更多过往日志可看:
|
|
266
265
|
|
|
267
|
-
[change_log.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/
|
|
266
|
+
[change_log.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/change_log.md )
|
|
268
267
|
|
|
269
268
|
## Star 历史趋势(Star History)
|
|
270
269
|
|
|
@@ -3,14 +3,14 @@ requires = ["setuptools>=61.0", "wheel"]
|
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
|
-
name = "celestialflow"
|
|
7
|
-
version = "3.2.
|
|
6
|
+
name = "celestialflow"
|
|
7
|
+
version = "3.2.2"
|
|
8
8
|
description = "A flexible GRAPH-based task orchestration framework."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
11
11
|
authors = [{ name = "Mr-xiaotian", email = "mingxiaomingtian@gmail.com" }]
|
|
12
12
|
keywords = ["workflow", "task", "graph", "async", "CelestialFlow"]
|
|
13
|
-
requires-python = ">=3.
|
|
13
|
+
requires-python = ">=3.11"
|
|
14
14
|
|
|
15
15
|
dependencies = [
|
|
16
16
|
"tqdm",
|
|
@@ -76,5 +76,40 @@ dev = [
|
|
|
76
76
|
|
|
77
77
|
[tool.pyright]
|
|
78
78
|
include = ["src"]
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
ignore = ["tests", "**/tests/**", "typings", "demo", "bench", "experiments", "examples", "temp"]
|
|
80
|
+
|
|
81
|
+
typeCheckingMode = "strict"
|
|
82
|
+
reportExplicitAny = "none"
|
|
83
|
+
reportAny = "none"
|
|
84
|
+
reportUnannotatedClassAttribute = "none"
|
|
85
|
+
reportUnusedFunction = "none"
|
|
86
|
+
reportImplicitOverride = "none"
|
|
87
|
+
|
|
88
|
+
[tool.ruff]
|
|
89
|
+
target-version = "py311"
|
|
90
|
+
exclude = ["tests", "typings", "demo", "bench", "experiments", "examples", "temp"]
|
|
91
|
+
|
|
92
|
+
[tool.ruff.lint]
|
|
93
|
+
select = [
|
|
94
|
+
"E", "F", # pycodestyle errors + pyflakes
|
|
95
|
+
"I", # isort (import order)
|
|
96
|
+
"UP", # pyupgrade
|
|
97
|
+
"B", # flake8-bugbear
|
|
98
|
+
"SIM", # flake8-simplify
|
|
99
|
+
"C4", # flake8-comprehensions
|
|
100
|
+
"RUF", # ruff-specific rules
|
|
101
|
+
]
|
|
102
|
+
ignore = [
|
|
103
|
+
"E501", # line too long(交给 formatter)
|
|
104
|
+
"RUF001", # 字符串内 Unicode 字符(中文内容)
|
|
105
|
+
"RUF002", # 中文标点(项目使用中文 docstring)
|
|
106
|
+
"RUF003", # 中文注释标点
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
[tool.ruff.format]
|
|
110
|
+
quote-style = "double"
|
|
111
|
+
indent-style = "space"
|
|
112
|
+
skip-magic-trailing-comma = false
|
|
113
|
+
|
|
114
|
+
[tool.ruff.lint.isort]
|
|
115
|
+
known-first-party = ["celestialflow"]
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
# __init__.py
|
|
2
|
+
"""CelestialFlow — 基于图结构的轻量级异步任务编排框架。
|
|
3
|
+
|
|
4
|
+
提供任务图构建、执行调度、实时监控、Web 可视化和持久化等核心能力。
|
|
5
|
+
"""
|
|
6
|
+
|
|
2
7
|
from .graph import (
|
|
3
8
|
TaskChain,
|
|
4
9
|
TaskComplete,
|
|
@@ -30,30 +35,30 @@ from .utils.util_format import format_table
|
|
|
30
35
|
from .web import TaskWebServer
|
|
31
36
|
|
|
32
37
|
__all__ = [
|
|
33
|
-
"
|
|
38
|
+
"BaseObserver",
|
|
39
|
+
"CallbackObserver",
|
|
34
40
|
"TaskChain",
|
|
35
|
-
"TaskLoop",
|
|
36
|
-
"TaskCross",
|
|
37
41
|
"TaskComplete",
|
|
38
|
-
"
|
|
42
|
+
"TaskCross",
|
|
43
|
+
"TaskExecutor",
|
|
44
|
+
"TaskGraph",
|
|
39
45
|
"TaskGrid",
|
|
40
|
-
"
|
|
41
|
-
"CallbackObserver",
|
|
46
|
+
"TaskLoop",
|
|
42
47
|
"TaskProgress",
|
|
43
|
-
"TaskExecutor",
|
|
44
|
-
"TaskStage",
|
|
45
|
-
"TaskSplitter",
|
|
46
|
-
"TaskRedisTransport",
|
|
47
|
-
"TaskRedisSource",
|
|
48
48
|
"TaskRedisAck",
|
|
49
|
+
"TaskRedisSource",
|
|
50
|
+
"TaskRedisTransport",
|
|
49
51
|
"TaskRouter",
|
|
50
|
-
"
|
|
52
|
+
"TaskSplitter",
|
|
53
|
+
"TaskStage",
|
|
51
54
|
"TaskWebServer",
|
|
55
|
+
"TaskWheel",
|
|
56
|
+
"TerminationSignal",
|
|
57
|
+
"benchmark_executor",
|
|
58
|
+
"benchmark_graph",
|
|
59
|
+
"format_table",
|
|
52
60
|
"load_jsonl_logs",
|
|
53
|
-
"load_task_by_stage",
|
|
54
61
|
"load_task_by_error",
|
|
62
|
+
"load_task_by_stage",
|
|
55
63
|
"make_hashable",
|
|
56
|
-
"format_table",
|
|
57
|
-
"benchmark_graph",
|
|
58
|
-
"benchmark_executor",
|
|
59
64
|
]
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
# funnel/core_inlet.py
|
|
2
|
-
from __future__ import annotations
|
|
3
|
-
|
|
4
|
-
from typing import Any
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class BaseInlet:
|
|
8
|
-
"""数据收集器基类,负责将记录通过队列发送到对应的监听器。"""
|
|
9
|
-
|
|
10
|
-
def __init__(self, queue: Any) -> None:
|
|
11
|
-
"""初始化收集器
|
|
12
|
-
|
|
13
|
-
:param queue: 记录队列
|
|
14
|
-
"""
|
|
15
|
-
self.queue: Any = queue
|
|
16
|
-
|
|
17
|
-
def _funnel(self, record: Any) -> None:
|
|
18
|
-
"""将记录放入队列
|
|
19
|
-
|
|
20
|
-
:param record: 待发送的记录
|
|
21
|
-
"""
|
|
22
|
-
self.queue.put(record)
|
|
1
|
+
# funnel/core_inlet.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseInlet:
|
|
8
|
+
"""数据收集器基类,负责将记录通过队列发送到对应的监听器。"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, queue: Any) -> None:
|
|
11
|
+
"""初始化收集器
|
|
12
|
+
|
|
13
|
+
:param queue: 记录队列
|
|
14
|
+
"""
|
|
15
|
+
self.queue: Any = queue
|
|
16
|
+
|
|
17
|
+
def _funnel(self, record: Any) -> None:
|
|
18
|
+
"""将记录放入队列
|
|
19
|
+
|
|
20
|
+
:param record: 待发送的记录
|
|
21
|
+
"""
|
|
22
|
+
self.queue.put(record)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# funnel/core_spout.py
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
+
import traceback
|
|
4
5
|
from queue import Empty, Queue
|
|
5
6
|
from threading import Thread
|
|
6
7
|
from typing import Any
|
|
7
8
|
|
|
9
|
+
from ..runtime.util_errors import CelestialFlowError
|
|
8
10
|
from ..runtime.util_types import TERMINATION_SIGNAL, TerminationSignal
|
|
9
11
|
|
|
10
12
|
|
|
@@ -17,12 +19,19 @@ class BaseSpout:
|
|
|
17
19
|
self._thread: Thread | None = None
|
|
18
20
|
|
|
19
21
|
def _before_start(self) -> None:
|
|
22
|
+
"""在后台线程启动前调用,子类可覆写以做初始化(如打开文件、清空缓存)。"""
|
|
20
23
|
return None
|
|
21
24
|
|
|
22
|
-
def _handle_record(self,
|
|
23
|
-
|
|
25
|
+
def _handle_record(self, _record: Any) -> None:
|
|
26
|
+
"""
|
|
27
|
+
处理单条队列记录,子类必须覆写。
|
|
28
|
+
|
|
29
|
+
:param _record: 队列中取出的记录
|
|
30
|
+
"""
|
|
31
|
+
raise CelestialFlowError("_handle_record must be implemented by subclasses")
|
|
24
32
|
|
|
25
33
|
def _after_stop(self) -> None:
|
|
34
|
+
"""在后台线程停止后调用,子类可覆写以做清理(如关闭文件句柄)。"""
|
|
26
35
|
return None
|
|
27
36
|
|
|
28
37
|
def start(self) -> None:
|
|
@@ -33,6 +42,7 @@ class BaseSpout:
|
|
|
33
42
|
self._thread.start()
|
|
34
43
|
|
|
35
44
|
def _spout(self) -> None:
|
|
45
|
+
"""后台线程主循环,持续从队列拉取记录并调用 _handle_record,收到终止信号时退出。"""
|
|
36
46
|
while True:
|
|
37
47
|
try:
|
|
38
48
|
record = self.queue.get(timeout=0.5)
|
|
@@ -41,8 +51,9 @@ class BaseSpout:
|
|
|
41
51
|
self._handle_record(record)
|
|
42
52
|
except Empty:
|
|
43
53
|
continue
|
|
44
|
-
except Exception:
|
|
45
|
-
|
|
54
|
+
except Exception:
|
|
55
|
+
# 单条记录处理失败不致死线程
|
|
56
|
+
traceback.print_exc()
|
|
46
57
|
|
|
47
58
|
def get_queue(self) -> Queue[Any]:
|
|
48
59
|
"""获取监听器的输入队列。"""
|
|
@@ -54,6 +65,7 @@ class BaseSpout:
|
|
|
54
65
|
return
|
|
55
66
|
|
|
56
67
|
self.queue.put(TERMINATION_SIGNAL)
|
|
57
|
-
self._thread.
|
|
68
|
+
if self._thread.is_alive():
|
|
69
|
+
self._thread.join(timeout=5)
|
|
58
70
|
self._thread = None
|
|
59
71
|
self._after_stop()
|