celestialflow 3.2.7__tar.gz → 3.2.9__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.7/src/celestialflow.egg-info → celestialflow-3.2.9}/PKG-INFO +92 -68
- {celestialflow-3.2.7 → celestialflow-3.2.9}/README.md +91 -67
- {celestialflow-3.2.7 → celestialflow-3.2.9}/pyproject.toml +7 -1
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/__init__.py +4 -3
- celestialflow-3.2.9/src/celestialflow/benchmark/__init__.py +6 -0
- celestialflow-3.2.9/src/celestialflow/benchmark/util_benchmark.py +129 -0
- {celestialflow-3.2.7/src/celestialflow/utils → celestialflow-3.2.9/src/celestialflow/benchmark}/util_clone.py +40 -21
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/funnel/core_spout.py +4 -1
- celestialflow-3.2.9/src/celestialflow/graph/core_graph.py +671 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/graph/core_structure.py +54 -58
- {celestialflow-3.2.7/src/celestialflow/runtime → celestialflow-3.2.9/src/celestialflow/graph}/util_estimators.py +15 -65
- celestialflow-3.2.7/src/celestialflow/graph/util_graph.py → celestialflow-3.2.9/src/celestialflow/graph/util_order_graph.py +58 -35
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/graph/util_serialize.py +149 -150
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/observability/__init__.py +2 -1
- celestialflow-3.2.9/src/celestialflow/observability/core_observer.py +112 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/observability/core_report.py +64 -56
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/observability/util_types.py +15 -8
- celestialflow-3.2.9/src/celestialflow/persistence/__init__.py +31 -0
- celestialflow-3.2.7/src/celestialflow/persistence/core_fallback.py → celestialflow-3.2.9/src/celestialflow/persistence/core_lifecycle.py +38 -53
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/persistence/core_log.py +99 -76
- celestialflow-3.2.9/src/celestialflow/persistence/core_scope.py +41 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/persistence/util_payload.py +2 -1
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/persistence/util_sqlite.py +9 -37
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/__init__.py +1 -4
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/core_envelope.py +11 -11
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/core_metrics.py +36 -13
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/core_queue.py +20 -25
- celestialflow-3.2.9/src/celestialflow/runtime/util_config.py +40 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/util_errors.py +7 -85
- celestialflow-3.2.9/src/celestialflow/runtime/util_estimators.py +68 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/util_event.py +62 -63
- {celestialflow-3.2.7/src/celestialflow/utils → celestialflow-3.2.9/src/celestialflow/runtime}/util_format.py +10 -18
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/util_hash.py +3 -3
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/util_types.py +2 -6
- {celestialflow-3.2.7/src/celestialflow/runtime → celestialflow-3.2.9/src/celestialflow/stage}/core_dispatch.py +72 -60
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/stage/core_executor.py +204 -222
- celestialflow-3.2.9/src/celestialflow/stage/core_stage.py +130 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/stage/core_stages.py +24 -26
- {celestialflow-3.2.7 → celestialflow-3.2.9/src/celestialflow.egg-info}/PKG-INFO +92 -68
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow.egg-info/SOURCES.txt +11 -9
- celestialflow-3.2.7/src/celestialflow/graph/core_graph.py +0 -690
- celestialflow-3.2.7/src/celestialflow/observability/core_observer.py +0 -51
- celestialflow-3.2.7/src/celestialflow/persistence/__init__.py +0 -15
- celestialflow-3.2.7/src/celestialflow/stage/core_stage.py +0 -237
- celestialflow-3.2.7/src/celestialflow/utils/__init__.py +0 -5
- celestialflow-3.2.7/src/celestialflow/utils/util_benchmark.py +0 -139
- celestialflow-3.2.7/src/celestialflow/utils/util_collections.py +0 -16
- {celestialflow-3.2.7 → celestialflow-3.2.9}/LICENSE +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/setup.cfg +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/funnel/__init__.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/funnel/core_inlet.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/funnel/util_count.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/graph/__init__.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/runtime/util_constant.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/stage/__init__.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/stage/util_callable.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow/stage/util_types.py +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow.egg-info/dependency_links.txt +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/src/celestialflow.egg-info/requires.txt +0 -0
- {celestialflow-3.2.7 → celestialflow-3.2.9}/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.9
|
|
4
4
|
Summary: A flexible GRAPH-based task orchestration framework.
|
|
5
5
|
Author-email: Mr-xiaotian <mingxiaomingtian@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -258,98 +258,122 @@ flowchart TD
|
|
|
258
258
|
## 文件结构(File Structure)
|
|
259
259
|
|
|
260
260
|
```
|
|
261
|
-
📁 CelestialFlow (
|
|
262
|
-
📁
|
|
263
|
-
📁
|
|
264
|
-
📁 .claude (99B)
|
|
265
|
-
🗄️ settings.local.json (99B)
|
|
266
|
-
📁 .github (601B)
|
|
267
|
-
📁 workflows[已折叠] (601B)
|
|
268
|
-
📁 bench (150KB 552B)
|
|
269
|
-
📁 [1项排除的目录] (47KB 905B)
|
|
261
|
+
📁 CelestialFlow (588MB 419KB 930B)
|
|
262
|
+
📁 bench (296KB 806B)
|
|
263
|
+
📁 [1项排除的目录] (194KB 222B)
|
|
270
264
|
🐍 bench_datastructures.py (6KB 690B)
|
|
271
|
-
🐍 bench_execution_mode.py (2KB
|
|
272
|
-
🐍 bench_futures_memory.py (2KB
|
|
273
|
-
🐍 bench_gil_vs_nogil.py (10KB
|
|
274
|
-
🐍 bench_graph_mode.py (7KB
|
|
275
|
-
🐍 bench_hash.py (7KB
|
|
265
|
+
🐍 bench_execution_mode.py (2KB 707B)
|
|
266
|
+
🐍 bench_futures_memory.py (2KB 269B)
|
|
267
|
+
🐍 bench_gil_vs_nogil.py (10KB 121B)
|
|
268
|
+
🐍 bench_graph_mode.py (7KB 450B)
|
|
269
|
+
🐍 bench_hash.py (7KB 67B)
|
|
276
270
|
🐍 bench_hash_container.py (3KB 1009B)
|
|
277
|
-
🐍 bench_hash_memory.py (3KB
|
|
278
|
-
🐍 bench_http_grpc.py (2KB
|
|
279
|
-
🐍 bench_ipc_queue.py (7KB
|
|
271
|
+
🐍 bench_hash_memory.py (3KB 642B)
|
|
272
|
+
🐍 bench_http_grpc.py (2KB 521B)
|
|
273
|
+
🐍 bench_ipc_queue.py (7KB 104B)
|
|
280
274
|
🐍 bench_lock_overhead.py (9KB 421B)
|
|
281
|
-
🐍 bench_mpqueue_vs_shared_memory.py (13KB
|
|
282
|
-
🐍 bench_observer.py (7KB
|
|
283
|
-
🐍 bench_persistence_spout.py (4KB
|
|
275
|
+
🐍 bench_mpqueue_vs_shared_memory.py (13KB 127B)
|
|
276
|
+
🐍 bench_observer.py (7KB 860B)
|
|
277
|
+
🐍 bench_persistence_spout.py (4KB 340B)
|
|
284
278
|
🐍 bench_queue.py (5KB 857B)
|
|
285
279
|
🐍 bench_requests.py (6KB 813B)
|
|
286
280
|
🐍 bench_tqdm.py (1KB 235B)
|
|
287
281
|
🐍 bench_utils.py (543B)
|
|
288
|
-
📁 demo
|
|
289
|
-
📁 [1项排除的目录] (
|
|
290
|
-
🐍 demo_executor.py (1KB
|
|
282
|
+
📁 demo (145KB 1012B)
|
|
283
|
+
📁 [1项排除的目录] (100KB 9B)
|
|
284
|
+
🐍 demo_executor.py (1KB 495B)
|
|
291
285
|
🐍 demo_funnel.py (2KB 289B)
|
|
292
|
-
🐍 demo_graph.py (3KB
|
|
293
|
-
🐍
|
|
294
|
-
🐍
|
|
295
|
-
🐍
|
|
296
|
-
🐍
|
|
297
|
-
🐍
|
|
298
|
-
|
|
286
|
+
🐍 demo_graph.py (3KB 227B)
|
|
287
|
+
🐍 demo_network.py (3KB 729B)
|
|
288
|
+
🐍 demo_observer.py (4KB 270B)
|
|
289
|
+
🐍 demo_redis.py (9KB 81B)
|
|
290
|
+
🐍 demo_stages.py (4KB 219B)
|
|
291
|
+
🐍 demo_structure.py (11KB 593B)
|
|
292
|
+
🐍 demo_utils.py (6KB 148B)
|
|
293
|
+
📁 dist (302KB 861B)
|
|
299
294
|
❓ .gitignore (1B)
|
|
300
|
-
❓ celestialflow-3.2.
|
|
301
|
-
📦 celestialflow-3.2.
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
📁
|
|
306
|
-
|
|
307
|
-
|
|
295
|
+
❓ celestialflow-3.2.7-py3-none-any.whl (79KB 235B)
|
|
296
|
+
📦 celestialflow-3.2.7.tar.gz (67KB 836B)
|
|
297
|
+
❓ celestialflow-3.2.8-py3-none-any.whl (83KB 244B)
|
|
298
|
+
📦 celestialflow-3.2.8.tar.gz (72KB 569B)
|
|
299
|
+
📁 docs (1MB 756KB 830B)
|
|
300
|
+
📁 en[已折叠] (568KB 991B)
|
|
301
|
+
📁 ja[已折叠] (642KB 383B)
|
|
302
|
+
📁 zh-CN[已折叠] (569KB 480B)
|
|
303
|
+
📁 experiments (2KB 1021B)
|
|
304
|
+
🐍 experiment_networkx.py (1KB 884B)
|
|
308
305
|
🐍 experiment_tqdm.py (1KB 137B)
|
|
309
|
-
📁 img
|
|
306
|
+
📁 img (5MB 871KB 242B)
|
|
310
307
|
📷 file_structure.svg (4MB 918KB 1000B)
|
|
311
308
|
📷 logo(old).png (836KB 542B)
|
|
312
309
|
📷 logo.png (122KB 747B)
|
|
313
310
|
📷 scc_condensation.svg (17KB 1B)
|
|
314
|
-
📁 src
|
|
315
|
-
📁 celestialflow[已折叠] (1MB
|
|
316
|
-
📁 celestialflow.egg-info[已折叠] (
|
|
317
|
-
📁 tests
|
|
318
|
-
📁
|
|
319
|
-
📁
|
|
320
|
-
📁
|
|
321
|
-
📁
|
|
322
|
-
📁
|
|
323
|
-
📁
|
|
324
|
-
📁
|
|
311
|
+
📁 src (1MB 873KB 44B)
|
|
312
|
+
📁 celestialflow[已折叠] (1MB 852KB 902B)
|
|
313
|
+
📁 celestialflow.egg-info[已折叠] (20KB 166B)
|
|
314
|
+
📁 tests (4MB 170KB 251B)
|
|
315
|
+
📁 benchmark[已折叠] (39KB 852B)
|
|
316
|
+
📁 funnel[已折叠] (96KB 363B)
|
|
317
|
+
📁 graph[已折叠] (724KB 404B)
|
|
318
|
+
📁 observability[已折叠] (189KB 230B)
|
|
319
|
+
📁 persistence[已折叠] (387KB 877B)
|
|
320
|
+
📁 runtime[已折叠] (1MB 295KB 264B)
|
|
321
|
+
📁 stage[已折叠] (381KB 203B)
|
|
322
|
+
📁 utils[已折叠] (639KB 527B)
|
|
325
323
|
📁 [1项排除的目录] (487KB 589B)
|
|
326
324
|
🐍 conftest.py (1KB 38B)
|
|
327
325
|
🐍 __init__.py (0B)
|
|
328
|
-
📁 [
|
|
329
|
-
❓ .env
|
|
330
|
-
❓ .gitignore
|
|
331
|
-
📝 AGENTS.md
|
|
332
|
-
❓ LICENSE
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
326
|
+
📁 [12项排除的目录] (573MB 949KB 913B)
|
|
327
|
+
❓ .env (468B)
|
|
328
|
+
❓ .gitignore (1KB 315B)
|
|
329
|
+
📝 AGENTS.md (1KB 434B)
|
|
330
|
+
❓ LICENSE (1KB 65B)
|
|
331
|
+
❓ Makefile (155B)
|
|
332
|
+
⚙️ pyproject.toml (2KB 668B)
|
|
333
|
+
📝 README.md (17KB 465B)
|
|
334
|
+
🔒 uv.lock (121KB 572B)
|
|
336
335
|
```
|
|
337
336
|
<p align="center">
|
|
338
|
-
<em>celestial-flow 3.2.
|
|
337
|
+
<em>celestial-flow 3.2.9</em>
|
|
339
338
|
</p>
|
|
340
339
|
|
|
341
340
|
(该视图由我的另一个项目[CelestialVault](https://github.com/Mr-xiaotian/CelestialVault)中inst_file.FileTree.print_tree()生成。转换为图片则借助[Carbon](https://carbon.now.sh)。)
|
|
342
341
|
|
|
343
342
|
## 版本日志(Version Log)
|
|
344
|
-
- 3.2.
|
|
343
|
+
- 3.2.9
|
|
345
344
|
- feat:
|
|
346
|
-
- `
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
-
|
|
351
|
-
|
|
352
|
-
|
|
345
|
+
- [IMPORTANT] 移除 `stage` 中 `stage_mode`,并添加 `graph_mode`
|
|
346
|
+
- 破坏性更新
|
|
347
|
+
- `stage_mode` 可以细粒度的控制每个 `TaskStage` 在图中的模式,但经过多年使用,我认为这种细粒度的控制并无必要,反而无谓的增加理解成本
|
|
348
|
+
- `graph_mode` 则提供了更粗粒度的控制,用于统一控制所有 `TaskStage` 在图中是串行/多线程/并发运行,适用于大多数场景
|
|
349
|
+
- 同时完善了 `graph_mode`(serial/thread/async) * `execution_mode`(serial/thread/async) 总共 9 种组合模式
|
|
350
|
+
- 移除 `schedule_mode`
|
|
351
|
+
- 破坏性更新
|
|
352
|
+
- 这个模式带来了许多复杂度,但没有与原先的 `stage_mode / execution_mode` 产生明显的组合优势
|
|
353
|
+
- 在 `get_graph_analysis` 中添加 `graph_mode`
|
|
354
|
+
- 这个函数主要用于给web端提供信息
|
|
355
|
+
- web端代码已经同步修改
|
|
356
|
+
- 添加新的 `warning` 项,当图不是 dag 且 `graph_mode=serial` 时触发
|
|
357
|
+
- 移除 `task_executor` 中的参数 `persist_result`
|
|
358
|
+
- 这是为了简化代码逻辑,同时也使所有任务的最终状态(包括:成功/失败/未执行)都能被统一存储
|
|
359
|
+
- 将 `task.retry` 事件降级,不再申请单独事件ID,不再在 `lifecycle` 中留痕
|
|
360
|
+
- reafactor:
|
|
361
|
+
- 合并 `benchmark` 相关函数对 sync 与 async 两种模式的执行
|
|
362
|
+
- 性能无差异,代码好看一些
|
|
363
|
+
- 将原本的 `fallback` 改名为 `lifecycle`
|
|
364
|
+
- 早在重构原本的 `fail` 时就想起个更恰当的名字,这个版本才实现
|
|
365
|
+
- 将 `graph.source_lists` 改为 `graph.source_names`
|
|
366
|
+
- `graph.source_lists` 直接存储节点的引用,而 `graph.source_names` 存储节点的名称
|
|
367
|
+
- 所有的 `log` / `lifecycle` 文件统一改名为 `flow_log` / `flow_lifecycle`
|
|
368
|
+
- 删除 `graph` 中的 `out_edges` `in_edges`
|
|
369
|
+
- 现在由 `OrderGraph` 负责管理边关系
|
|
370
|
+
- 在 `tarjan_scc` 中使用 DFS 取代原先的递归逻辑
|
|
371
|
+
- 将 `util_graph` 改名为 `util_order_graph`
|
|
372
|
+
- fix:
|
|
373
|
+
- 修复最后一次 report 无法正常上传的问题
|
|
374
|
+
- 修复 `graph.run` / `graph.run_async` 中 `is_put_signal` 参数没有生效的问题
|
|
375
|
+
- chore:
|
|
376
|
+
- 更新文档
|
|
353
377
|
|
|
354
378
|
更多过往日志可看:
|
|
355
379
|
|
|
@@ -239,98 +239,122 @@ flowchart TD
|
|
|
239
239
|
## 文件结构(File Structure)
|
|
240
240
|
|
|
241
241
|
```
|
|
242
|
-
📁 CelestialFlow (
|
|
243
|
-
📁
|
|
244
|
-
📁
|
|
245
|
-
📁 .claude (99B)
|
|
246
|
-
🗄️ settings.local.json (99B)
|
|
247
|
-
📁 .github (601B)
|
|
248
|
-
📁 workflows[已折叠] (601B)
|
|
249
|
-
📁 bench (150KB 552B)
|
|
250
|
-
📁 [1项排除的目录] (47KB 905B)
|
|
242
|
+
📁 CelestialFlow (588MB 419KB 930B)
|
|
243
|
+
📁 bench (296KB 806B)
|
|
244
|
+
📁 [1项排除的目录] (194KB 222B)
|
|
251
245
|
🐍 bench_datastructures.py (6KB 690B)
|
|
252
|
-
🐍 bench_execution_mode.py (2KB
|
|
253
|
-
🐍 bench_futures_memory.py (2KB
|
|
254
|
-
🐍 bench_gil_vs_nogil.py (10KB
|
|
255
|
-
🐍 bench_graph_mode.py (7KB
|
|
256
|
-
🐍 bench_hash.py (7KB
|
|
246
|
+
🐍 bench_execution_mode.py (2KB 707B)
|
|
247
|
+
🐍 bench_futures_memory.py (2KB 269B)
|
|
248
|
+
🐍 bench_gil_vs_nogil.py (10KB 121B)
|
|
249
|
+
🐍 bench_graph_mode.py (7KB 450B)
|
|
250
|
+
🐍 bench_hash.py (7KB 67B)
|
|
257
251
|
🐍 bench_hash_container.py (3KB 1009B)
|
|
258
|
-
🐍 bench_hash_memory.py (3KB
|
|
259
|
-
🐍 bench_http_grpc.py (2KB
|
|
260
|
-
🐍 bench_ipc_queue.py (7KB
|
|
252
|
+
🐍 bench_hash_memory.py (3KB 642B)
|
|
253
|
+
🐍 bench_http_grpc.py (2KB 521B)
|
|
254
|
+
🐍 bench_ipc_queue.py (7KB 104B)
|
|
261
255
|
🐍 bench_lock_overhead.py (9KB 421B)
|
|
262
|
-
🐍 bench_mpqueue_vs_shared_memory.py (13KB
|
|
263
|
-
🐍 bench_observer.py (7KB
|
|
264
|
-
🐍 bench_persistence_spout.py (4KB
|
|
256
|
+
🐍 bench_mpqueue_vs_shared_memory.py (13KB 127B)
|
|
257
|
+
🐍 bench_observer.py (7KB 860B)
|
|
258
|
+
🐍 bench_persistence_spout.py (4KB 340B)
|
|
265
259
|
🐍 bench_queue.py (5KB 857B)
|
|
266
260
|
🐍 bench_requests.py (6KB 813B)
|
|
267
261
|
🐍 bench_tqdm.py (1KB 235B)
|
|
268
262
|
🐍 bench_utils.py (543B)
|
|
269
|
-
📁 demo
|
|
270
|
-
📁 [1项排除的目录] (
|
|
271
|
-
🐍 demo_executor.py (1KB
|
|
263
|
+
📁 demo (145KB 1012B)
|
|
264
|
+
📁 [1项排除的目录] (100KB 9B)
|
|
265
|
+
🐍 demo_executor.py (1KB 495B)
|
|
272
266
|
🐍 demo_funnel.py (2KB 289B)
|
|
273
|
-
🐍 demo_graph.py (3KB
|
|
274
|
-
🐍
|
|
275
|
-
🐍
|
|
276
|
-
🐍
|
|
277
|
-
🐍
|
|
278
|
-
🐍
|
|
279
|
-
|
|
267
|
+
🐍 demo_graph.py (3KB 227B)
|
|
268
|
+
🐍 demo_network.py (3KB 729B)
|
|
269
|
+
🐍 demo_observer.py (4KB 270B)
|
|
270
|
+
🐍 demo_redis.py (9KB 81B)
|
|
271
|
+
🐍 demo_stages.py (4KB 219B)
|
|
272
|
+
🐍 demo_structure.py (11KB 593B)
|
|
273
|
+
🐍 demo_utils.py (6KB 148B)
|
|
274
|
+
📁 dist (302KB 861B)
|
|
280
275
|
❓ .gitignore (1B)
|
|
281
|
-
❓ celestialflow-3.2.
|
|
282
|
-
📦 celestialflow-3.2.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
📁
|
|
287
|
-
|
|
288
|
-
|
|
276
|
+
❓ celestialflow-3.2.7-py3-none-any.whl (79KB 235B)
|
|
277
|
+
📦 celestialflow-3.2.7.tar.gz (67KB 836B)
|
|
278
|
+
❓ celestialflow-3.2.8-py3-none-any.whl (83KB 244B)
|
|
279
|
+
📦 celestialflow-3.2.8.tar.gz (72KB 569B)
|
|
280
|
+
📁 docs (1MB 756KB 830B)
|
|
281
|
+
📁 en[已折叠] (568KB 991B)
|
|
282
|
+
📁 ja[已折叠] (642KB 383B)
|
|
283
|
+
📁 zh-CN[已折叠] (569KB 480B)
|
|
284
|
+
📁 experiments (2KB 1021B)
|
|
285
|
+
🐍 experiment_networkx.py (1KB 884B)
|
|
289
286
|
🐍 experiment_tqdm.py (1KB 137B)
|
|
290
|
-
📁 img
|
|
287
|
+
📁 img (5MB 871KB 242B)
|
|
291
288
|
📷 file_structure.svg (4MB 918KB 1000B)
|
|
292
289
|
📷 logo(old).png (836KB 542B)
|
|
293
290
|
📷 logo.png (122KB 747B)
|
|
294
291
|
📷 scc_condensation.svg (17KB 1B)
|
|
295
|
-
📁 src
|
|
296
|
-
📁 celestialflow[已折叠] (1MB
|
|
297
|
-
📁 celestialflow.egg-info[已折叠] (
|
|
298
|
-
📁 tests
|
|
299
|
-
📁
|
|
300
|
-
📁
|
|
301
|
-
📁
|
|
302
|
-
📁
|
|
303
|
-
📁
|
|
304
|
-
📁
|
|
305
|
-
📁
|
|
292
|
+
📁 src (1MB 873KB 44B)
|
|
293
|
+
📁 celestialflow[已折叠] (1MB 852KB 902B)
|
|
294
|
+
📁 celestialflow.egg-info[已折叠] (20KB 166B)
|
|
295
|
+
📁 tests (4MB 170KB 251B)
|
|
296
|
+
📁 benchmark[已折叠] (39KB 852B)
|
|
297
|
+
📁 funnel[已折叠] (96KB 363B)
|
|
298
|
+
📁 graph[已折叠] (724KB 404B)
|
|
299
|
+
📁 observability[已折叠] (189KB 230B)
|
|
300
|
+
📁 persistence[已折叠] (387KB 877B)
|
|
301
|
+
📁 runtime[已折叠] (1MB 295KB 264B)
|
|
302
|
+
📁 stage[已折叠] (381KB 203B)
|
|
303
|
+
📁 utils[已折叠] (639KB 527B)
|
|
306
304
|
📁 [1项排除的目录] (487KB 589B)
|
|
307
305
|
🐍 conftest.py (1KB 38B)
|
|
308
306
|
🐍 __init__.py (0B)
|
|
309
|
-
📁 [
|
|
310
|
-
❓ .env
|
|
311
|
-
❓ .gitignore
|
|
312
|
-
📝 AGENTS.md
|
|
313
|
-
❓ LICENSE
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
307
|
+
📁 [12项排除的目录] (573MB 949KB 913B)
|
|
308
|
+
❓ .env (468B)
|
|
309
|
+
❓ .gitignore (1KB 315B)
|
|
310
|
+
📝 AGENTS.md (1KB 434B)
|
|
311
|
+
❓ LICENSE (1KB 65B)
|
|
312
|
+
❓ Makefile (155B)
|
|
313
|
+
⚙️ pyproject.toml (2KB 668B)
|
|
314
|
+
📝 README.md (17KB 465B)
|
|
315
|
+
🔒 uv.lock (121KB 572B)
|
|
317
316
|
```
|
|
318
317
|
<p align="center">
|
|
319
|
-
<em>celestial-flow 3.2.
|
|
318
|
+
<em>celestial-flow 3.2.9</em>
|
|
320
319
|
</p>
|
|
321
320
|
|
|
322
321
|
(该视图由我的另一个项目[CelestialVault](https://github.com/Mr-xiaotian/CelestialVault)中inst_file.FileTree.print_tree()生成。转换为图片则借助[Carbon](https://carbon.now.sh)。)
|
|
323
322
|
|
|
324
323
|
## 版本日志(Version Log)
|
|
325
|
-
- 3.2.
|
|
324
|
+
- 3.2.9
|
|
326
325
|
- feat:
|
|
327
|
-
- `
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
-
|
|
332
|
-
|
|
333
|
-
|
|
326
|
+
- [IMPORTANT] 移除 `stage` 中 `stage_mode`,并添加 `graph_mode`
|
|
327
|
+
- 破坏性更新
|
|
328
|
+
- `stage_mode` 可以细粒度的控制每个 `TaskStage` 在图中的模式,但经过多年使用,我认为这种细粒度的控制并无必要,反而无谓的增加理解成本
|
|
329
|
+
- `graph_mode` 则提供了更粗粒度的控制,用于统一控制所有 `TaskStage` 在图中是串行/多线程/并发运行,适用于大多数场景
|
|
330
|
+
- 同时完善了 `graph_mode`(serial/thread/async) * `execution_mode`(serial/thread/async) 总共 9 种组合模式
|
|
331
|
+
- 移除 `schedule_mode`
|
|
332
|
+
- 破坏性更新
|
|
333
|
+
- 这个模式带来了许多复杂度,但没有与原先的 `stage_mode / execution_mode` 产生明显的组合优势
|
|
334
|
+
- 在 `get_graph_analysis` 中添加 `graph_mode`
|
|
335
|
+
- 这个函数主要用于给web端提供信息
|
|
336
|
+
- web端代码已经同步修改
|
|
337
|
+
- 添加新的 `warning` 项,当图不是 dag 且 `graph_mode=serial` 时触发
|
|
338
|
+
- 移除 `task_executor` 中的参数 `persist_result`
|
|
339
|
+
- 这是为了简化代码逻辑,同时也使所有任务的最终状态(包括:成功/失败/未执行)都能被统一存储
|
|
340
|
+
- 将 `task.retry` 事件降级,不再申请单独事件ID,不再在 `lifecycle` 中留痕
|
|
341
|
+
- reafactor:
|
|
342
|
+
- 合并 `benchmark` 相关函数对 sync 与 async 两种模式的执行
|
|
343
|
+
- 性能无差异,代码好看一些
|
|
344
|
+
- 将原本的 `fallback` 改名为 `lifecycle`
|
|
345
|
+
- 早在重构原本的 `fail` 时就想起个更恰当的名字,这个版本才实现
|
|
346
|
+
- 将 `graph.source_lists` 改为 `graph.source_names`
|
|
347
|
+
- `graph.source_lists` 直接存储节点的引用,而 `graph.source_names` 存储节点的名称
|
|
348
|
+
- 所有的 `log` / `lifecycle` 文件统一改名为 `flow_log` / `flow_lifecycle`
|
|
349
|
+
- 删除 `graph` 中的 `out_edges` `in_edges`
|
|
350
|
+
- 现在由 `OrderGraph` 负责管理边关系
|
|
351
|
+
- 在 `tarjan_scc` 中使用 DFS 取代原先的递归逻辑
|
|
352
|
+
- 将 `util_graph` 改名为 `util_order_graph`
|
|
353
|
+
- fix:
|
|
354
|
+
- 修复最后一次 report 无法正常上传的问题
|
|
355
|
+
- 修复 `graph.run` / `graph.run_async` 中 `is_put_signal` 参数没有生效的问题
|
|
356
|
+
- chore:
|
|
357
|
+
- 更新文档
|
|
334
358
|
|
|
335
359
|
更多过往日志可看:
|
|
336
360
|
|
|
@@ -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.9"
|
|
8
8
|
description = "A flexible GRAPH-based task orchestration framework."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -27,6 +27,9 @@ classifiers = [
|
|
|
27
27
|
"Homepage" = "https://github.com/Mr-xiaotian/CelestialFlow"
|
|
28
28
|
"Bug Tracker" = "https://github.com/Mr-xiaotian/CelestialFlow/issues"
|
|
29
29
|
|
|
30
|
+
[tool.uv]
|
|
31
|
+
index-url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
|
32
|
+
|
|
30
33
|
[tool.pytest.ini_options]
|
|
31
34
|
addopts = "-s"
|
|
32
35
|
log_cli = true
|
|
@@ -56,6 +59,9 @@ dev = [
|
|
|
56
59
|
"tqdm",
|
|
57
60
|
]
|
|
58
61
|
|
|
62
|
+
[tool.celestialflow]
|
|
63
|
+
log_level = "INFO"
|
|
64
|
+
|
|
59
65
|
[tool.pyright]
|
|
60
66
|
include = ["src"]
|
|
61
67
|
ignore = ["tests", "**/tests/**", "typings", "demo", "bench", "experiments", "examples", "temp"]
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
提供任务图构建、执行调度、实时监控与持久化等核心能力。
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from .benchmark.util_benchmark import benchmark_executor, benchmark_graph
|
|
7
8
|
from .funnel import BaseInlet, BaseSpout
|
|
8
9
|
from .graph import (
|
|
9
10
|
TaskChain,
|
|
@@ -14,11 +15,12 @@ from .graph import (
|
|
|
14
15
|
TaskLoop,
|
|
15
16
|
TaskWheel,
|
|
16
17
|
)
|
|
17
|
-
from .observability import BaseObserver
|
|
18
|
+
from .observability import BaseObserver, TaskReporter
|
|
18
19
|
from .persistence.util_sqlite import (
|
|
19
20
|
load_records,
|
|
20
21
|
load_tasks_grouped_by_stage,
|
|
21
22
|
)
|
|
23
|
+
from .runtime.util_format import format_table
|
|
22
24
|
from .runtime.util_hash import make_hashable
|
|
23
25
|
from .runtime.util_types import TerminationSignal
|
|
24
26
|
from .stage import (
|
|
@@ -27,8 +29,6 @@ from .stage import (
|
|
|
27
29
|
TaskSplitter,
|
|
28
30
|
TaskStage,
|
|
29
31
|
)
|
|
30
|
-
from .utils.util_benchmark import benchmark_executor, benchmark_graph
|
|
31
|
-
from .utils.util_format import format_table
|
|
32
32
|
|
|
33
33
|
__all__ = [
|
|
34
34
|
"BaseInlet",
|
|
@@ -41,6 +41,7 @@ __all__ = [
|
|
|
41
41
|
"TaskGraph",
|
|
42
42
|
"TaskGrid",
|
|
43
43
|
"TaskLoop",
|
|
44
|
+
"TaskReporter",
|
|
44
45
|
"TaskRouter",
|
|
45
46
|
"TaskSplitter",
|
|
46
47
|
"TaskStage",
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# benchmark/util_benchmark.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import asyncio
|
|
5
|
+
import time
|
|
6
|
+
from collections.abc import Iterable, Mapping
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from ..graph import TaskGraph
|
|
10
|
+
from ..runtime.util_format import format_table
|
|
11
|
+
from ..stage import TaskExecutor
|
|
12
|
+
from .util_clone import clone_executor, clone_graph
|
|
13
|
+
|
|
14
|
+
type AnyTaskExecutor = TaskExecutor[Any, Any]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def benchmark_executor(
|
|
18
|
+
sync_executor: AnyTaskExecutor,
|
|
19
|
+
async_executor: AnyTaskExecutor,
|
|
20
|
+
task_source: Iterable[Any],
|
|
21
|
+
execution_modes: list[str] | None = None,
|
|
22
|
+
) -> dict[str, Any]:
|
|
23
|
+
"""
|
|
24
|
+
对执行器进行基准测试
|
|
25
|
+
|
|
26
|
+
:param sync_executor: 同步执行器模板(用于 serial/thread execution_mode)
|
|
27
|
+
:param async_executor: 异步执行器模板(用于 async execution_mode)
|
|
28
|
+
:param task_source: 任务源,用于生成任务列表
|
|
29
|
+
:param execution_modes: 执行模式列表,默认 ["serial", "thread", "async"]
|
|
30
|
+
:return: 包含测试结果的字典
|
|
31
|
+
"""
|
|
32
|
+
task_list: list[Any] = list(task_source)
|
|
33
|
+
execution_modes = execution_modes or ["serial", "thread", "async"]
|
|
34
|
+
|
|
35
|
+
use_time: list[list[float]] = []
|
|
36
|
+
for mode in execution_modes:
|
|
37
|
+
if mode == "async":
|
|
38
|
+
cloned_executor = clone_executor(async_executor)
|
|
39
|
+
else:
|
|
40
|
+
cloned_executor = clone_executor(sync_executor)
|
|
41
|
+
cloned_executor.set_execution_mode(mode)
|
|
42
|
+
|
|
43
|
+
start = time.perf_counter()
|
|
44
|
+
if mode == "async":
|
|
45
|
+
await cloned_executor.run_async(task_list)
|
|
46
|
+
else:
|
|
47
|
+
cloned_executor.run(task_list)
|
|
48
|
+
use_time.append([time.perf_counter() - start])
|
|
49
|
+
|
|
50
|
+
use_time_table: str = format_table(use_time, execution_modes, ["Time"])
|
|
51
|
+
print(f"Use time:\n{use_time_table}\n")
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
"use_time": use_time,
|
|
55
|
+
"execution_modes": execution_modes,
|
|
56
|
+
"table": use_time_table,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def benchmark_graph(
|
|
61
|
+
sync_graph: TaskGraph,
|
|
62
|
+
async_graph: TaskGraph,
|
|
63
|
+
init_tasks_dict: Mapping[str, Iterable[Any]],
|
|
64
|
+
graph_modes: list[str] | None = None,
|
|
65
|
+
execution_modes: list[str] | None = None,
|
|
66
|
+
) -> dict[str, Any]:
|
|
67
|
+
"""
|
|
68
|
+
对任务图进行基准测试,覆盖 ``graph_mode × execution_mode`` 的全部组合。
|
|
69
|
+
|
|
70
|
+
- ``sync_graph`` 用于 ``execution_mode in {"serial", "thread"}`` 的单元格;
|
|
71
|
+
- ``async_graph`` 用于 ``execution_mode == "async"`` 的单元格;
|
|
72
|
+
- ``graph_mode`` 决定当前单元格使用 ``run()`` 还是 ``run_async()`` 启动。
|
|
73
|
+
|
|
74
|
+
:param sync_graph: 同步任务图模板(用于 serial/thread execution_mode)
|
|
75
|
+
:param async_graph: 异步任务图模板(用于 async execution_mode)
|
|
76
|
+
:param init_tasks_dict: 初始任务字典,键为任务标签,值为任务列表
|
|
77
|
+
:param graph_modes: 要测试的图执行模式列表,默认包括 "serial", "thread", "async"
|
|
78
|
+
:param execution_modes: 执行模式列表,默认 ["serial", "thread", "async"]
|
|
79
|
+
:return: 包含测试结果的字典
|
|
80
|
+
"""
|
|
81
|
+
graph_modes = graph_modes or ["serial", "thread", "async"]
|
|
82
|
+
execution_modes = execution_modes or ["serial", "thread", "async"]
|
|
83
|
+
|
|
84
|
+
base_tasks: dict[str, list[Any]] = {
|
|
85
|
+
stage_name: list(tasks) for stage_name, tasks in init_tasks_dict.items()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
test_table_list: list[list[float]] = []
|
|
89
|
+
|
|
90
|
+
for graph_mode in graph_modes:
|
|
91
|
+
time_list: list[float] = []
|
|
92
|
+
|
|
93
|
+
for execution_mode in execution_modes:
|
|
94
|
+
cloned_graph = (
|
|
95
|
+
clone_graph(async_graph)
|
|
96
|
+
if execution_mode == "async"
|
|
97
|
+
else clone_graph(sync_graph)
|
|
98
|
+
)
|
|
99
|
+
cloned_graph.set_graph_mode(graph_mode)
|
|
100
|
+
cloned_graph.set_stage_execution_mode(execution_mode)
|
|
101
|
+
|
|
102
|
+
run_tasks: dict[str, Iterable[Any]] = {
|
|
103
|
+
stage_name: list(tasks) for stage_name, tasks in base_tasks.items()
|
|
104
|
+
}
|
|
105
|
+
start_time = time.perf_counter()
|
|
106
|
+
if graph_mode == "async":
|
|
107
|
+
await cloned_graph.run_async(run_tasks)
|
|
108
|
+
else:
|
|
109
|
+
if execution_mode == "async":
|
|
110
|
+
await asyncio.to_thread(cloned_graph.run, run_tasks)
|
|
111
|
+
else:
|
|
112
|
+
cloned_graph.run(run_tasks)
|
|
113
|
+
time_list.append(time.perf_counter() - start_time)
|
|
114
|
+
|
|
115
|
+
test_table_list.append(time_list)
|
|
116
|
+
|
|
117
|
+
time_table: str = format_table(
|
|
118
|
+
test_table_list,
|
|
119
|
+
graph_modes,
|
|
120
|
+
execution_modes,
|
|
121
|
+
"graph/execution",
|
|
122
|
+
)
|
|
123
|
+
print(f"Time table:\n{time_table}")
|
|
124
|
+
return {
|
|
125
|
+
"use_time": test_table_list,
|
|
126
|
+
"table": time_table,
|
|
127
|
+
"graph_modes": graph_modes,
|
|
128
|
+
"execution_modes": execution_modes,
|
|
129
|
+
}
|