celestialflow 3.2.6__tar.gz → 3.2.7__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.6/src/celestialflow.egg-info → celestialflow-3.2.7}/PKG-INFO +104 -21
- {celestialflow-3.2.6 → celestialflow-3.2.7}/README.md +103 -19
- {celestialflow-3.2.6 → celestialflow-3.2.7}/pyproject.toml +3 -2
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/__init__.py +1 -2
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/graph/core_graph.py +11 -3
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/observability/__init__.py +0 -2
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/core_dispatch.py +7 -2
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/core_metrics.py +41 -1
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/core_queue.py +10 -23
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/stage/core_executor.py +14 -42
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/stage/core_stage.py +237 -236
- {celestialflow-3.2.6 → celestialflow-3.2.7/src/celestialflow.egg-info}/PKG-INFO +104 -21
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow.egg-info/SOURCES.txt +0 -1
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow.egg-info/requires.txt +0 -1
- celestialflow-3.2.6/src/celestialflow/observability/core_progress.py +0 -61
- {celestialflow-3.2.6 → celestialflow-3.2.7}/LICENSE +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/setup.cfg +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/funnel/__init__.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/funnel/core_inlet.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/funnel/core_spout.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/funnel/util_count.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/graph/__init__.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/graph/core_structure.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/graph/util_graph.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/graph/util_serialize.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/observability/core_observer.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/observability/core_report.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/observability/util_types.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/persistence/__init__.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/persistence/core_fallback.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/persistence/core_log.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/persistence/util_payload.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/persistence/util_sqlite.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/__init__.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/core_envelope.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/util_constant.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/util_errors.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/util_estimators.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/util_event.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/util_hash.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/runtime/util_types.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/stage/__init__.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/stage/core_stages.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/stage/util_callable.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/stage/util_types.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/utils/__init__.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/utils/util_benchmark.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/utils/util_clone.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/utils/util_collections.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow/utils/util_format.py +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/src/celestialflow.egg-info/dependency_links.txt +0 -0
- {celestialflow-3.2.6 → celestialflow-3.2.7}/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.7
|
|
4
4
|
Summary: A flexible GRAPH-based task orchestration framework.
|
|
5
5
|
Author-email: Mr-xiaotian <mingxiaomingtian@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -14,7 +14,6 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
14
14
|
Requires-Python: >=3.12
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: tqdm
|
|
18
17
|
Requires-Dist: requests
|
|
19
18
|
Dynamic: license-file
|
|
20
19
|
|
|
@@ -134,16 +133,27 @@ uv sync --group dev
|
|
|
134
133
|
```python
|
|
135
134
|
from celestialflow import TaskStage, TaskGraph
|
|
136
135
|
|
|
137
|
-
|
|
136
|
+
|
|
137
|
+
def add(x, y):
|
|
138
138
|
return x + y
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
|
|
141
|
+
def square(x):
|
|
142
|
+
return x**2
|
|
143
|
+
|
|
142
144
|
|
|
143
145
|
if __name__ == "__main__":
|
|
144
146
|
# 定义两个任务节点
|
|
145
|
-
stage1 = TaskStage(
|
|
146
|
-
|
|
147
|
+
stage1 = TaskStage(
|
|
148
|
+
name="Adder",
|
|
149
|
+
func=add,
|
|
150
|
+
stage_mode="thread",
|
|
151
|
+
execution_mode="thread",
|
|
152
|
+
unpack_task_args=True,
|
|
153
|
+
)
|
|
154
|
+
stage2 = TaskStage(
|
|
155
|
+
name="Squarer", func=square, stage_mode="thread", execution_mode="thread"
|
|
156
|
+
)
|
|
147
157
|
|
|
148
158
|
# 构建任务图结构
|
|
149
159
|
graph = TaskGraph(name="DemoGraph")
|
|
@@ -165,12 +175,12 @@ if __name__ == "__main__":
|
|
|
165
175
|
- [TaskExecutor.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/stage/core_executor.md)
|
|
166
176
|
- [TaskStage.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/stage/core_stage.md)
|
|
167
177
|
- [TaskGraph.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/graph/core_graph.md)
|
|
168
|
-
- [TaskProgress.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/observability/core_progress.md)
|
|
169
178
|
- [TaskMetrics.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/core_metrics.md)
|
|
170
179
|
- [TaskQueue.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/core_queue.md)
|
|
171
180
|
- [TaskStages.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/stage/core_stages.md)
|
|
172
181
|
- [TaskReport.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/observability/core_report.md)
|
|
173
182
|
- [TaskStructure.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/graph/core_structure.md)
|
|
183
|
+
- [BaseObserver.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/observability/core_observer.md)
|
|
174
184
|
- [Go Worker.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/other/go_worker.md)
|
|
175
185
|
|
|
176
186
|
推荐阅读顺序:
|
|
@@ -183,7 +193,7 @@ flowchart TD
|
|
|
183
193
|
classDef execution fill:#f3e8ff,stroke:#a855f7,color:#581c87;
|
|
184
194
|
|
|
185
195
|
TM[TaskExecutor.md] --> TS[TaskStage.md] --> TG[TaskGraph.md]
|
|
186
|
-
TM -->
|
|
196
|
+
TM --> OB[BaseObserver.md]
|
|
187
197
|
TM --> TME[TaskMetrics.md]
|
|
188
198
|
|
|
189
199
|
TG --> TQ[TaskQueue.md]
|
|
@@ -247,26 +257,99 @@ flowchart TD
|
|
|
247
257
|
|
|
248
258
|
## 文件结构(File Structure)
|
|
249
259
|
|
|
260
|
+
```
|
|
261
|
+
📁 CelestialFlow (471MB 982KB 22B)
|
|
262
|
+
📁 .agents (55KB 152B)
|
|
263
|
+
📁 skills[已折叠] (55KB 152B)
|
|
264
|
+
📁 .claude (99B)
|
|
265
|
+
🗄️ settings.local.json (99B)
|
|
266
|
+
📁 .github (601B)
|
|
267
|
+
📁 workflows[已折叠] (601B)
|
|
268
|
+
📁 bench (150KB 552B)
|
|
269
|
+
📁 [1项排除的目录] (47KB 905B)
|
|
270
|
+
🐍 bench_datastructures.py (6KB 690B)
|
|
271
|
+
🐍 bench_execution_mode.py (2KB 889B)
|
|
272
|
+
🐍 bench_futures_memory.py (2KB 267B)
|
|
273
|
+
🐍 bench_gil_vs_nogil.py (10KB 159B)
|
|
274
|
+
🐍 bench_graph_mode.py (7KB 173B)
|
|
275
|
+
🐍 bench_hash.py (7KB 39B)
|
|
276
|
+
🐍 bench_hash_container.py (3KB 1009B)
|
|
277
|
+
🐍 bench_hash_memory.py (3KB 613B)
|
|
278
|
+
🐍 bench_http_grpc.py (2KB 883B)
|
|
279
|
+
🐍 bench_ipc_queue.py (7KB 74B)
|
|
280
|
+
🐍 bench_lock_overhead.py (9KB 421B)
|
|
281
|
+
🐍 bench_mpqueue_vs_shared_memory.py (13KB 106B)
|
|
282
|
+
🐍 bench_observer.py (7KB 899B)
|
|
283
|
+
🐍 bench_persistence_spout.py (4KB 193B)
|
|
284
|
+
🐍 bench_queue.py (5KB 857B)
|
|
285
|
+
🐍 bench_requests.py (6KB 813B)
|
|
286
|
+
🐍 bench_tqdm.py (1KB 235B)
|
|
287
|
+
🐍 bench_utils.py (543B)
|
|
288
|
+
📁 demo (105KB 440B)
|
|
289
|
+
📁 [1项排除的目录] (61KB 883B)
|
|
290
|
+
🐍 demo_executor.py (1KB 504B)
|
|
291
|
+
🐍 demo_funnel.py (2KB 289B)
|
|
292
|
+
🐍 demo_graph.py (3KB 615B)
|
|
293
|
+
🐍 demo_observer.py (4KB 293B)
|
|
294
|
+
🐍 demo_redis.py (9KB 201B)
|
|
295
|
+
🐍 demo_stages.py (4KB 519B)
|
|
296
|
+
🐍 demo_structure.py (12KB 8B)
|
|
297
|
+
🐍 demo_utils.py (6KB 200B)
|
|
298
|
+
📁 dist (145KB 290B)
|
|
299
|
+
❓ .gitignore (1B)
|
|
300
|
+
❓ celestialflow-3.2.6-py3-none-any.whl (78KB 975B)
|
|
301
|
+
📦 celestialflow-3.2.6.tar.gz (66KB 338B)
|
|
302
|
+
📁 docs (1MB 712KB 884B)
|
|
303
|
+
📁 en[已折叠] (569KB 485B)
|
|
304
|
+
📁 ja[已折叠] (642KB 959B)
|
|
305
|
+
📁 zh-CN[已折叠] (524KB 464B)
|
|
306
|
+
📁 experiments (2KB 1015B)
|
|
307
|
+
🐍 experiment_networkx.py (1KB 878B)
|
|
308
|
+
🐍 experiment_tqdm.py (1KB 137B)
|
|
309
|
+
📁 img (5MB 871KB 242B)
|
|
310
|
+
📷 file_structure.svg (4MB 918KB 1000B)
|
|
311
|
+
📷 logo(old).png (836KB 542B)
|
|
312
|
+
📷 logo.png (122KB 747B)
|
|
313
|
+
📷 scc_condensation.svg (17KB 1B)
|
|
314
|
+
📁 src (1MB 767KB 296B)
|
|
315
|
+
📁 celestialflow[已折叠] (1MB 752KB 195B)
|
|
316
|
+
📁 celestialflow.egg-info[已折叠] (15KB 101B)
|
|
317
|
+
📁 tests (3MB 902KB 217B)
|
|
318
|
+
📁 funnel[已折叠] (96KB 481B)
|
|
319
|
+
📁 graph[已折叠] (631KB 532B)
|
|
320
|
+
📁 observability[已折叠] (157KB 435B)
|
|
321
|
+
📁 persistence[已折叠] (359KB 68B)
|
|
322
|
+
📁 runtime[已折叠] (1MB 286KB 487B)
|
|
323
|
+
📁 stage[已折叠] (281KB 752B)
|
|
324
|
+
📁 utils[已折叠] (648KB 931B)
|
|
325
|
+
📁 [1项排除的目录] (487KB 589B)
|
|
326
|
+
🐍 conftest.py (1KB 38B)
|
|
327
|
+
🐍 __init__.py (0B)
|
|
328
|
+
📁 [9项排除的目录] (458MB 223KB 525B)
|
|
329
|
+
❓ .env (468B)
|
|
330
|
+
❓ .gitignore (1KB 313B)
|
|
331
|
+
📝 AGENTS.md (971B)
|
|
332
|
+
❓ LICENSE (1KB 65B)
|
|
333
|
+
⚙️ pyproject.toml (2KB 555B)
|
|
334
|
+
📝 README.md (12KB 272B)
|
|
335
|
+
🔒 uv.lock (98KB 257B)
|
|
336
|
+
```
|
|
250
337
|
<p align="center">
|
|
251
|
-
<
|
|
252
|
-
<br/>
|
|
253
|
-
<em>celestial-flow 3.2.6</em>
|
|
338
|
+
<em>celestial-flow 3.2.7</em>
|
|
254
339
|
</p>
|
|
255
340
|
|
|
256
341
|
(该视图由我的另一个项目[CelestialVault](https://github.com/Mr-xiaotian/CelestialVault)中inst_file.FileTree.print_tree()生成。转换为图片则借助[Carbon](https://carbon.now.sh)。)
|
|
257
342
|
|
|
258
343
|
## 版本日志(Version Log)
|
|
259
|
-
- 3.2.
|
|
344
|
+
- 3.2.7
|
|
260
345
|
- feat:
|
|
261
|
-
-
|
|
262
|
-
|
|
346
|
+
- `TaskInQueue` 中添加 `maxsize` 参数, 用于限制队列最大长度
|
|
347
|
+
- 在 `graph.connect` 中添加对两个stage输入输出参数类型的检验, 如果不通过, 会有pyright报错
|
|
263
348
|
- refactor:
|
|
264
|
-
-
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
|
|
268
|
-
- 全量更新文档, 并翻译为en/ja双语言
|
|
269
|
-
- 移除 docs/zh-CN 下的 `README.md`, 现在中文readme只保留根目录下的这一份
|
|
349
|
+
- 移除对 `tqdm` 的依赖
|
|
350
|
+
- 根据 `bench\bench_observer.py`, tqdm对轻量级任务影响有限
|
|
351
|
+
- 这次移除主要是为了完成尽量零第三方库依赖的目标
|
|
352
|
+
- 将 `observer` 的管理从 `executor` 转到 `metric`
|
|
270
353
|
|
|
271
354
|
更多过往日志可看:
|
|
272
355
|
|
|
@@ -114,16 +114,27 @@ uv sync --group dev
|
|
|
114
114
|
```python
|
|
115
115
|
from celestialflow import TaskStage, TaskGraph
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
|
|
118
|
+
def add(x, y):
|
|
118
119
|
return x + y
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
|
|
122
|
+
def square(x):
|
|
123
|
+
return x**2
|
|
124
|
+
|
|
122
125
|
|
|
123
126
|
if __name__ == "__main__":
|
|
124
127
|
# 定义两个任务节点
|
|
125
|
-
stage1 = TaskStage(
|
|
126
|
-
|
|
128
|
+
stage1 = TaskStage(
|
|
129
|
+
name="Adder",
|
|
130
|
+
func=add,
|
|
131
|
+
stage_mode="thread",
|
|
132
|
+
execution_mode="thread",
|
|
133
|
+
unpack_task_args=True,
|
|
134
|
+
)
|
|
135
|
+
stage2 = TaskStage(
|
|
136
|
+
name="Squarer", func=square, stage_mode="thread", execution_mode="thread"
|
|
137
|
+
)
|
|
127
138
|
|
|
128
139
|
# 构建任务图结构
|
|
129
140
|
graph = TaskGraph(name="DemoGraph")
|
|
@@ -145,12 +156,12 @@ if __name__ == "__main__":
|
|
|
145
156
|
- [TaskExecutor.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/stage/core_executor.md)
|
|
146
157
|
- [TaskStage.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/stage/core_stage.md)
|
|
147
158
|
- [TaskGraph.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/graph/core_graph.md)
|
|
148
|
-
- [TaskProgress.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/observability/core_progress.md)
|
|
149
159
|
- [TaskMetrics.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/core_metrics.md)
|
|
150
160
|
- [TaskQueue.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/runtime/core_queue.md)
|
|
151
161
|
- [TaskStages.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/stage/core_stages.md)
|
|
152
162
|
- [TaskReport.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/observability/core_report.md)
|
|
153
163
|
- [TaskStructure.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/graph/core_structure.md)
|
|
164
|
+
- [BaseObserver.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/src/observability/core_observer.md)
|
|
154
165
|
- [Go Worker.md](https://github.com/Mr-xiaotian/CelestialFlow/blob/main/docs/zh-CN/other/go_worker.md)
|
|
155
166
|
|
|
156
167
|
推荐阅读顺序:
|
|
@@ -163,7 +174,7 @@ flowchart TD
|
|
|
163
174
|
classDef execution fill:#f3e8ff,stroke:#a855f7,color:#581c87;
|
|
164
175
|
|
|
165
176
|
TM[TaskExecutor.md] --> TS[TaskStage.md] --> TG[TaskGraph.md]
|
|
166
|
-
TM -->
|
|
177
|
+
TM --> OB[BaseObserver.md]
|
|
167
178
|
TM --> TME[TaskMetrics.md]
|
|
168
179
|
|
|
169
180
|
TG --> TQ[TaskQueue.md]
|
|
@@ -227,26 +238,99 @@ flowchart TD
|
|
|
227
238
|
|
|
228
239
|
## 文件结构(File Structure)
|
|
229
240
|
|
|
241
|
+
```
|
|
242
|
+
📁 CelestialFlow (471MB 982KB 22B)
|
|
243
|
+
📁 .agents (55KB 152B)
|
|
244
|
+
📁 skills[已折叠] (55KB 152B)
|
|
245
|
+
📁 .claude (99B)
|
|
246
|
+
🗄️ settings.local.json (99B)
|
|
247
|
+
📁 .github (601B)
|
|
248
|
+
📁 workflows[已折叠] (601B)
|
|
249
|
+
📁 bench (150KB 552B)
|
|
250
|
+
📁 [1项排除的目录] (47KB 905B)
|
|
251
|
+
🐍 bench_datastructures.py (6KB 690B)
|
|
252
|
+
🐍 bench_execution_mode.py (2KB 889B)
|
|
253
|
+
🐍 bench_futures_memory.py (2KB 267B)
|
|
254
|
+
🐍 bench_gil_vs_nogil.py (10KB 159B)
|
|
255
|
+
🐍 bench_graph_mode.py (7KB 173B)
|
|
256
|
+
🐍 bench_hash.py (7KB 39B)
|
|
257
|
+
🐍 bench_hash_container.py (3KB 1009B)
|
|
258
|
+
🐍 bench_hash_memory.py (3KB 613B)
|
|
259
|
+
🐍 bench_http_grpc.py (2KB 883B)
|
|
260
|
+
🐍 bench_ipc_queue.py (7KB 74B)
|
|
261
|
+
🐍 bench_lock_overhead.py (9KB 421B)
|
|
262
|
+
🐍 bench_mpqueue_vs_shared_memory.py (13KB 106B)
|
|
263
|
+
🐍 bench_observer.py (7KB 899B)
|
|
264
|
+
🐍 bench_persistence_spout.py (4KB 193B)
|
|
265
|
+
🐍 bench_queue.py (5KB 857B)
|
|
266
|
+
🐍 bench_requests.py (6KB 813B)
|
|
267
|
+
🐍 bench_tqdm.py (1KB 235B)
|
|
268
|
+
🐍 bench_utils.py (543B)
|
|
269
|
+
📁 demo (105KB 440B)
|
|
270
|
+
📁 [1项排除的目录] (61KB 883B)
|
|
271
|
+
🐍 demo_executor.py (1KB 504B)
|
|
272
|
+
🐍 demo_funnel.py (2KB 289B)
|
|
273
|
+
🐍 demo_graph.py (3KB 615B)
|
|
274
|
+
🐍 demo_observer.py (4KB 293B)
|
|
275
|
+
🐍 demo_redis.py (9KB 201B)
|
|
276
|
+
🐍 demo_stages.py (4KB 519B)
|
|
277
|
+
🐍 demo_structure.py (12KB 8B)
|
|
278
|
+
🐍 demo_utils.py (6KB 200B)
|
|
279
|
+
📁 dist (145KB 290B)
|
|
280
|
+
❓ .gitignore (1B)
|
|
281
|
+
❓ celestialflow-3.2.6-py3-none-any.whl (78KB 975B)
|
|
282
|
+
📦 celestialflow-3.2.6.tar.gz (66KB 338B)
|
|
283
|
+
📁 docs (1MB 712KB 884B)
|
|
284
|
+
📁 en[已折叠] (569KB 485B)
|
|
285
|
+
📁 ja[已折叠] (642KB 959B)
|
|
286
|
+
📁 zh-CN[已折叠] (524KB 464B)
|
|
287
|
+
📁 experiments (2KB 1015B)
|
|
288
|
+
🐍 experiment_networkx.py (1KB 878B)
|
|
289
|
+
🐍 experiment_tqdm.py (1KB 137B)
|
|
290
|
+
📁 img (5MB 871KB 242B)
|
|
291
|
+
📷 file_structure.svg (4MB 918KB 1000B)
|
|
292
|
+
📷 logo(old).png (836KB 542B)
|
|
293
|
+
📷 logo.png (122KB 747B)
|
|
294
|
+
📷 scc_condensation.svg (17KB 1B)
|
|
295
|
+
📁 src (1MB 767KB 296B)
|
|
296
|
+
📁 celestialflow[已折叠] (1MB 752KB 195B)
|
|
297
|
+
📁 celestialflow.egg-info[已折叠] (15KB 101B)
|
|
298
|
+
📁 tests (3MB 902KB 217B)
|
|
299
|
+
📁 funnel[已折叠] (96KB 481B)
|
|
300
|
+
📁 graph[已折叠] (631KB 532B)
|
|
301
|
+
📁 observability[已折叠] (157KB 435B)
|
|
302
|
+
📁 persistence[已折叠] (359KB 68B)
|
|
303
|
+
📁 runtime[已折叠] (1MB 286KB 487B)
|
|
304
|
+
📁 stage[已折叠] (281KB 752B)
|
|
305
|
+
📁 utils[已折叠] (648KB 931B)
|
|
306
|
+
📁 [1项排除的目录] (487KB 589B)
|
|
307
|
+
🐍 conftest.py (1KB 38B)
|
|
308
|
+
🐍 __init__.py (0B)
|
|
309
|
+
📁 [9项排除的目录] (458MB 223KB 525B)
|
|
310
|
+
❓ .env (468B)
|
|
311
|
+
❓ .gitignore (1KB 313B)
|
|
312
|
+
📝 AGENTS.md (971B)
|
|
313
|
+
❓ LICENSE (1KB 65B)
|
|
314
|
+
⚙️ pyproject.toml (2KB 555B)
|
|
315
|
+
📝 README.md (12KB 272B)
|
|
316
|
+
🔒 uv.lock (98KB 257B)
|
|
317
|
+
```
|
|
230
318
|
<p align="center">
|
|
231
|
-
<
|
|
232
|
-
<br/>
|
|
233
|
-
<em>celestial-flow 3.2.6</em>
|
|
319
|
+
<em>celestial-flow 3.2.7</em>
|
|
234
320
|
</p>
|
|
235
321
|
|
|
236
322
|
(该视图由我的另一个项目[CelestialVault](https://github.com/Mr-xiaotian/CelestialVault)中inst_file.FileTree.print_tree()生成。转换为图片则借助[Carbon](https://carbon.now.sh)。)
|
|
237
323
|
|
|
238
324
|
## 版本日志(Version Log)
|
|
239
|
-
- 3.2.
|
|
325
|
+
- 3.2.7
|
|
240
326
|
- feat:
|
|
241
|
-
-
|
|
242
|
-
|
|
327
|
+
- `TaskInQueue` 中添加 `maxsize` 参数, 用于限制队列最大长度
|
|
328
|
+
- 在 `graph.connect` 中添加对两个stage输入输出参数类型的检验, 如果不通过, 会有pyright报错
|
|
243
329
|
- refactor:
|
|
244
|
-
-
|
|
245
|
-
-
|
|
246
|
-
-
|
|
247
|
-
|
|
248
|
-
- 全量更新文档, 并翻译为en/ja双语言
|
|
249
|
-
- 移除 docs/zh-CN 下的 `README.md`, 现在中文readme只保留根目录下的这一份
|
|
330
|
+
- 移除对 `tqdm` 的依赖
|
|
331
|
+
- 根据 `bench\bench_observer.py`, tqdm对轻量级任务影响有限
|
|
332
|
+
- 这次移除主要是为了完成尽量零第三方库依赖的目标
|
|
333
|
+
- 将 `observer` 的管理从 `executor` 转到 `metric`
|
|
250
334
|
|
|
251
335
|
更多过往日志可看:
|
|
252
336
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "celestialflow"
|
|
7
|
-
version = "3.2.
|
|
7
|
+
version = "3.2.7"
|
|
8
8
|
description = "A flexible GRAPH-based task orchestration framework."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -13,7 +13,6 @@ keywords = ["workflow", "task", "graph", "async", "CelestialFlow"]
|
|
|
13
13
|
requires-python = ">=3.12"
|
|
14
14
|
|
|
15
15
|
dependencies = [
|
|
16
|
-
"tqdm",
|
|
17
16
|
"requests",
|
|
18
17
|
]
|
|
19
18
|
|
|
@@ -54,12 +53,14 @@ dev = [
|
|
|
54
53
|
"pyright>=1.1.409",
|
|
55
54
|
"redis",
|
|
56
55
|
"celestialtree>=0.1.3",
|
|
56
|
+
"tqdm",
|
|
57
57
|
]
|
|
58
58
|
|
|
59
59
|
[tool.pyright]
|
|
60
60
|
include = ["src"]
|
|
61
61
|
ignore = ["tests", "**/tests/**", "typings", "demo", "bench", "experiments", "examples", "temp"]
|
|
62
62
|
|
|
63
|
+
pythonVersion = "3.14"
|
|
63
64
|
typeCheckingMode = "strict"
|
|
64
65
|
reportUnusedFunction = "none"
|
|
65
66
|
reportImplicitOverride = "none"
|
|
@@ -14,7 +14,7 @@ from .graph import (
|
|
|
14
14
|
TaskLoop,
|
|
15
15
|
TaskWheel,
|
|
16
16
|
)
|
|
17
|
-
from .observability import BaseObserver
|
|
17
|
+
from .observability import BaseObserver
|
|
18
18
|
from .persistence.util_sqlite import (
|
|
19
19
|
load_records,
|
|
20
20
|
load_tasks_grouped_by_stage,
|
|
@@ -41,7 +41,6 @@ __all__ = [
|
|
|
41
41
|
"TaskGraph",
|
|
42
42
|
"TaskGrid",
|
|
43
43
|
"TaskLoop",
|
|
44
|
-
"TaskProgress",
|
|
45
44
|
"TaskRouter",
|
|
46
45
|
"TaskSplitter",
|
|
47
46
|
"TaskStage",
|
|
@@ -27,6 +27,7 @@ from ..runtime.util_estimators import (
|
|
|
27
27
|
)
|
|
28
28
|
from ..runtime.util_event import EventClient, LocalEventClient
|
|
29
29
|
from ..runtime.util_types import TerminationSignal
|
|
30
|
+
from ..stage.core_stage import TaskStage
|
|
30
31
|
from ..stage.util_types import AnyTaskStage
|
|
31
32
|
from ..utils.util_collections import cluster_by_value_sorted
|
|
32
33
|
from ..utils.util_format import format_avg_time
|
|
@@ -103,20 +104,27 @@ class TaskGraph:
|
|
|
103
104
|
"""
|
|
104
105
|
# 用于保存所有子线程的引用
|
|
105
106
|
self.threads: list[threading.Thread] = []
|
|
107
|
+
|
|
106
108
|
# 用于保存每个节点的运行信息
|
|
107
109
|
self.stage_dict: dict[str, AnyTaskStage] = {}
|
|
110
|
+
|
|
108
111
|
# 用于保存每个节点的上一次collect_runtime_snapshot()的状态信息
|
|
109
112
|
self.status_dict: dict[str, dict[str, Any]] = defaultdict(dict)
|
|
113
|
+
|
|
110
114
|
# 用于保存最近一次状态快照对应的统一时间戳
|
|
111
115
|
self.status_timestamp: float = 0.0
|
|
116
|
+
|
|
112
117
|
# 用于保存每个节点的输入任务ID集合
|
|
113
118
|
self.input_ids: dict[str, set[int]] = defaultdict(set)
|
|
119
|
+
|
|
114
120
|
# 用于保存源节点列表(由 _build_analysis 自动计算)
|
|
115
121
|
self.source_stages: list[AnyTaskStage] = []
|
|
122
|
+
|
|
116
123
|
# 用于保存图结构的邻接表
|
|
117
124
|
self.out_edges: dict[str, list[str]] = defaultdict(list)
|
|
118
125
|
self.in_edges: dict[str, list[str]] = defaultdict(list)
|
|
119
126
|
self.order_graph = OrderGraph()
|
|
127
|
+
|
|
120
128
|
# 用于保存任务图启动时间
|
|
121
129
|
self.start_time: float = 0.0
|
|
122
130
|
|
|
@@ -157,10 +165,10 @@ class TaskGraph:
|
|
|
157
165
|
stage.set_ctree(self.ctree_client)
|
|
158
166
|
stage.set_inlet(self.fallback_inlet, self.log_inlet)
|
|
159
167
|
|
|
160
|
-
def connect(
|
|
168
|
+
def connect[R](
|
|
161
169
|
self,
|
|
162
|
-
from_stages: list[
|
|
163
|
-
to_stages: list[
|
|
170
|
+
from_stages: list[TaskStage[Any, R]],
|
|
171
|
+
to_stages: list[TaskStage[R, Any]],
|
|
164
172
|
) -> None:
|
|
165
173
|
"""
|
|
166
174
|
建立超边连接:from_stages 中的每个节点连接到 to_stages 中的每个节点。
|
|
@@ -210,9 +210,14 @@ class TaskDispatch[T, R]:
|
|
|
210
210
|
if self._pool is None:
|
|
211
211
|
raise InitializationError("execution pool has not been initialized")
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
# 等待在途任务数低于水位线
|
|
214
|
+
while True:
|
|
215
|
+
# 清理已完成的任务
|
|
215
216
|
futures = [f for f in futures if not f.done()]
|
|
217
|
+
if len(futures) < self.max_workers:
|
|
218
|
+
break
|
|
219
|
+
time.sleep(0.001) # 简短让出
|
|
220
|
+
futures.append(self._pool.submit(self._worker, envelope))
|
|
216
221
|
|
|
217
222
|
# 等待当前批次的所有任务完成
|
|
218
223
|
for future in futures:
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from threading import Lock
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
5
6
|
|
|
6
7
|
from .util_types import SumCounter, ValueWrapper
|
|
7
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ..observability import BaseObserver
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
class TaskMetrics:
|
|
10
14
|
"""
|
|
@@ -35,6 +39,7 @@ class TaskMetrics:
|
|
|
35
39
|
"""
|
|
36
40
|
self.enable_duplicate_check = enable_duplicate_check
|
|
37
41
|
self.retry_exceptions = ()
|
|
42
|
+
self._observers: list[BaseObserver] = []
|
|
38
43
|
|
|
39
44
|
self.lock = Lock()
|
|
40
45
|
self._init_counter()
|
|
@@ -51,6 +56,7 @@ class TaskMetrics:
|
|
|
51
56
|
self.error_counter = ValueWrapper(value=0, lock=self.lock)
|
|
52
57
|
self.duplicate_counter = ValueWrapper(value=0, lock=self.lock)
|
|
53
58
|
|
|
59
|
+
# ==== 重置 ====
|
|
54
60
|
def reset_counter(self) -> None:
|
|
55
61
|
"""
|
|
56
62
|
重置计数器
|
|
@@ -69,6 +75,23 @@ class TaskMetrics:
|
|
|
69
75
|
"""
|
|
70
76
|
self.processed_set = set() # task_hash
|
|
71
77
|
|
|
78
|
+
# ==== 观察者 ====
|
|
79
|
+
def add_observer(self, observer: BaseObserver) -> None:
|
|
80
|
+
"""
|
|
81
|
+
注册观察者。
|
|
82
|
+
|
|
83
|
+
:param observer: 要注册的观察者实例
|
|
84
|
+
"""
|
|
85
|
+
self._observers.append(observer)
|
|
86
|
+
|
|
87
|
+
def remove_observer(self, observer: BaseObserver) -> None:
|
|
88
|
+
"""
|
|
89
|
+
移除观察者。
|
|
90
|
+
|
|
91
|
+
:param observer: 要移除的观察者实例
|
|
92
|
+
"""
|
|
93
|
+
self._observers.remove(observer)
|
|
94
|
+
|
|
72
95
|
# ==== 去重 ====
|
|
73
96
|
def is_duplicate(self, task_hash: bytes) -> bool:
|
|
74
97
|
"""
|
|
@@ -125,6 +148,8 @@ class TaskMetrics:
|
|
|
125
148
|
:param add_count: 增加的任务数
|
|
126
149
|
"""
|
|
127
150
|
self.task_counter.add(add_count)
|
|
151
|
+
for observer in self._observers:
|
|
152
|
+
observer.on_tasks_added(add_count)
|
|
128
153
|
|
|
129
154
|
def add_success_count(self, count: int = 1) -> None:
|
|
130
155
|
"""
|
|
@@ -135,8 +160,10 @@ class TaskMetrics:
|
|
|
135
160
|
:param count: 增加的成功任务数量,默认值为 1。
|
|
136
161
|
"""
|
|
137
162
|
self.success_counter.add(count)
|
|
163
|
+
for observer in self._observers:
|
|
164
|
+
observer.on_task_success(count)
|
|
138
165
|
|
|
139
|
-
def
|
|
166
|
+
def add_fail_count(self, count: int = 1) -> None:
|
|
140
167
|
"""
|
|
141
168
|
更新失败任务计数器
|
|
142
169
|
|
|
@@ -145,6 +172,8 @@ class TaskMetrics:
|
|
|
145
172
|
:param count: 增加的失败任务数量,默认值为 1。
|
|
146
173
|
"""
|
|
147
174
|
self.error_counter.add(count)
|
|
175
|
+
for observer in self._observers:
|
|
176
|
+
observer.on_task_fail(count)
|
|
148
177
|
|
|
149
178
|
def add_duplicate_count(self, count: int = 1) -> None:
|
|
150
179
|
"""
|
|
@@ -155,6 +184,17 @@ class TaskMetrics:
|
|
|
155
184
|
:param count: 增加的重复任务数量,默认值为 1。
|
|
156
185
|
"""
|
|
157
186
|
self.duplicate_counter.add(count)
|
|
187
|
+
for observer in self._observers:
|
|
188
|
+
observer.on_task_duplicate(count)
|
|
189
|
+
|
|
190
|
+
# ==== 启动与结束 ====
|
|
191
|
+
def on_start(self, _name: str, _total: int) -> None:
|
|
192
|
+
for observer in self._observers:
|
|
193
|
+
observer.on_start(_name, _total)
|
|
194
|
+
|
|
195
|
+
def on_finish(self) -> None:
|
|
196
|
+
for observer in self._observers:
|
|
197
|
+
observer.on_finish()
|
|
158
198
|
|
|
159
199
|
# ==== 查询 ====
|
|
160
200
|
def is_tasks_finished(self) -> bool:
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# runtime/core_queue.py
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
-
from queue import Empty
|
|
4
|
+
from queue import Empty, Queue
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
7
|
from .core_envelope import TaskEnvelope
|
|
8
8
|
from .util_errors import (
|
|
9
|
-
ConfigurationError,
|
|
10
9
|
DuplicateNodeError,
|
|
11
10
|
TerminationMergeError,
|
|
12
11
|
UnknownNodeError,
|
|
@@ -18,29 +17,27 @@ from .util_types import TerminationIdPool, TerminationSignal
|
|
|
18
17
|
class TaskInQueue[T]:
|
|
19
18
|
"""任务输入队列,聚合多个上游来源的任务和终止信号。"""
|
|
20
19
|
|
|
20
|
+
out_name: str
|
|
21
21
|
queue: Any
|
|
22
22
|
source_names: list[str]
|
|
23
|
-
out_name: str
|
|
24
23
|
termination_dict: dict[str, int]
|
|
25
24
|
|
|
26
25
|
# ==== 初始化 ====
|
|
27
26
|
def __init__(
|
|
28
27
|
self,
|
|
29
|
-
queue: Any,
|
|
30
|
-
source_names: list[str],
|
|
31
28
|
out_name: str,
|
|
29
|
+
maxsize: int = 0,
|
|
32
30
|
) -> None:
|
|
33
31
|
"""
|
|
34
32
|
初始化任务入队
|
|
35
33
|
|
|
36
|
-
:param queue: 队列对象
|
|
37
|
-
:param source_names: 上游节点名称列表
|
|
38
34
|
:param out_name: 当前节点唯一名称
|
|
35
|
+
:param maxsize: 队列最大容量,默认为 0(无限制)
|
|
39
36
|
"""
|
|
40
|
-
self.queue = queue
|
|
41
|
-
self.source_names = source_names
|
|
42
37
|
self.out_name = out_name
|
|
38
|
+
self.queue = Queue(maxsize=maxsize)
|
|
43
39
|
|
|
40
|
+
self.source_names = []
|
|
44
41
|
self.termination_dict = {}
|
|
45
42
|
|
|
46
43
|
# ==== 添加 ====
|
|
@@ -181,36 +178,26 @@ class TaskInQueue[T]:
|
|
|
181
178
|
class TaskOutQueue[T]:
|
|
182
179
|
"""任务输出队列,将任务广播到一个或多个下游队列通道。"""
|
|
183
180
|
|
|
181
|
+
in_name: str
|
|
184
182
|
queue_list: list[Any]
|
|
185
183
|
target_names: list[str]
|
|
186
|
-
in_name: str
|
|
187
184
|
_name_to_idx: dict[str, int]
|
|
188
185
|
|
|
189
186
|
# ==== 初始化 ====
|
|
190
187
|
def __init__(
|
|
191
188
|
self,
|
|
192
|
-
queue_list: list[Any],
|
|
193
|
-
target_names: list[str],
|
|
194
189
|
in_name: str,
|
|
195
190
|
) -> None:
|
|
196
191
|
"""
|
|
197
192
|
任务输出队列类,用于管理多个输出队列
|
|
198
193
|
|
|
199
|
-
:param queue_list: 输出队列列表,每个元素为一个线程队列或异步队列
|
|
200
|
-
:param target_names: 下游节点名称列表,用于标识每个队列
|
|
201
194
|
:param in_name: 当前节点唯一名称,用于记录日志
|
|
202
|
-
:raises ConfigurationError: 如果队列列表和目标名称列表长度不一致
|
|
203
195
|
"""
|
|
204
|
-
if len(queue_list) != len(target_names):
|
|
205
|
-
raise ConfigurationError(
|
|
206
|
-
"queue_list and target_names must have the same length"
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
self.queue_list = queue_list
|
|
210
|
-
self.target_names = target_names
|
|
211
196
|
self.in_name = in_name
|
|
212
197
|
|
|
213
|
-
self.
|
|
198
|
+
self.queue_list = []
|
|
199
|
+
self.target_names = []
|
|
200
|
+
self._name_to_idx = {}
|
|
214
201
|
|
|
215
202
|
# ==== put ====
|
|
216
203
|
|