{"id":31970409,"url":"https://github.com/symphony09/running","last_synced_at":"2025-10-14T19:14:55.001Z","repository":{"id":41083289,"uuid":"489867263","full_name":"symphony09/running","owner":"symphony09","description":"Golang DAG 图化执行引擎","archived":false,"fork":false,"pushed_at":"2023-08-06T11:04:46.000Z","size":174,"stargazers_count":15,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-06-20T16:33:39.841Z","etag":null,"topics":["dag","go","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/symphony09.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-08T06:42:05.000Z","updated_at":"2024-06-05T05:25:36.000Z","dependencies_parsed_at":"2024-06-20T16:18:35.334Z","dependency_job_id":"23d731fb-bc5b-4118-8b0f-e2377a54a3bb","html_url":"https://github.com/symphony09/running","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/symphony09/running","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/symphony09%2Frunning","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/symphony09%2Frunning/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/symphony09%2Frunning/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/symphony09%2Frunning/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/symphony09","download_url":"https://codeload.github.com/symphony09/running/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/symphony09%2Frunning/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279020649,"owners_count":26086895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dag","go","golang"],"created_at":"2025-10-14T19:14:49.065Z","updated_at":"2025-10-14T19:14:54.996Z","avatar_url":"https://github.com/symphony09.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Running 一个简单的图节点执行框架\n\n与其他图节点执行框架一样，running 也是将任务抽象为节点，将依赖关系抽象为边。\n\n节点与边一起构成了图，也就是整个执行流程的抽象。\n\n如何组织节点，按照预定的流程执行，就是 running 要解决的问题。\n\n## 主要特点\n\n### 注重并发执行场景\n\nrunning 的设计注重许多任务需要并发执行的场景。所以它适合在线计算任务，而非离线计算任务。\n\n例如 running 在执行过程中实时计算依赖，而非预先计算执行步骤，顺序执行。只要上游依赖解决，那么节点就会尽快运行。\n\n此外 running 还着重考虑了冷启动问题，缓解瞬时高并发造成的性能问题。\n\n### 支持定义复杂执行流程\n\n在某些情况下，纯粹用图定义执行流程是比较困难的。\n\n比如循环和分支选择流程，running 定义了簇 cluster 来解决这个问题。\n\ncluster 是一类特殊的节点，它包含了若干个子节点，这些子节点的执行时机不再通过计算依赖关系确定，而是由 cluster 决定。\n\n因为 cluster 也属于节点，所以它也可以嵌套在其他的 cluster 中，实现更加复杂的流程。\n\n### 动态增强节点\n\n将任务逻辑封装为节点，不可避免地会带来一定的心智负担。\n\nrunning 定义了装饰器 wrapper 来动态增强节点，使用组合的理念降低负担。\n\n一是增加节点的可复用性，避免需要频繁封装类似功能的节点。二是增加灵活性，新功能随用随加。\n\nwrapper 也是一类特殊的节点，它包含要增强的目标节点，可以在目标节点执行前后执行增强逻辑。并且也可以嵌套。\n\n### 方便地导出和载入图定义\n\nrunning 支持对构建好的图进行序列化和反序列化，方便不同环境同步。\n\n例如，工作流程在测试环境验证完成后，导出序列化图，线上环境热加载图定义就可以马上同步工作流程。\n\n## 如何入手\n\n### package common\n\ncommon 包定义了一些通用的 cluster 、wrapper 和 node 实现。\n\n结合对应 test 代码和方法注释就可以基本掌握如何使用 running。\n\n十分建议在阅读完本文档后，阅读这些代码。有错误的地方也欢迎指出。\n\n### running.Engine\n\nrunning.Engine 提供了一组方法用于注册节点构建函数，管理计划（包括图定义和节点初始化参数）和 worker 池。\n\n考虑到对 Engine 的定制需求较少，running 初始化了一个全局变量并暴露对应了方法。\n\n因此可以直接调用 running.RegisterNodeBuilder 等函数，无需自行创建 Engine 实例来调用其方法。\n\n有需要的话，如出于隔离目的，也可以使用 running.NewDefaultEngine 创建新的 Engine 实例。\n\n### running.Plan\n\nplan 包含了图定义和节点的初始化参数，图定义通过一系列操作选项确定。\n\n将 plan 通过 RegisterPlan 注册到 engine 中后，就可以调用 ExecPlan 执行。\n\n创建 plan 的函数签名如下：\n\n```func NewPlan(props Props, prebuilt []Node, options ...Option) *Plan```\n\n- props 即节点参数，running 提供了一个基于 map[string]interface{} 的实现 StandardProps。\n  - key 基于约定设为 节点名.参数名，value 为参数值\n- prebuilt 为预建节点，需要实现 Clone 方法，可以用于减少运行过程中节点构建消耗\n- options 即操作选项，包括连接节点，合并节点为 cluster，包装节点等\n  - 具体操作类型请参考 plan_options.go 及 test 代码\n\n### running.Base \u0026 running.BaseWrapper\n\n为了简化代码封装，running 提供 running.Base 和 running.BaseWrapper\n\n将 running.Base 嵌入结构体后就自动实现了 Node 和 Cluster 接口的大部分方法，running.BaseWrapper 则实现 Wrapper 的接口方法，\n只需再实现 Run 方法即可。 如果通用实现不满足要求，按需求重写对应方法即可。\n\n### running.State\n\nrunning.State 用于运行时节点间通信。只要实现 running.Stateful 接口, 节点在运行时就会被绑定 state。\n\n通过对 state 增改查就能实现节点间的通信。\n\n要注意的是，running 提供了 State 的一个实现 StandardState ，\nStandardState 通过读写锁在一定程度上可以保证并发安全，但是前提是对于 Query 得到的对象不要做任何修改（尤其是引用类型）。\n需要做修改时，使用 Update 方法或 Transform 方法。\n\n在安全性或性能上有定制需求时，可以自行实现 State 接口，并设置 Engine 的 StateBuilder。\n\n## 状态和路线图\n\n目前项目任然处于初期阶段，不建议生产使用，同时欢迎提交 issue 来让 running 变得更好。\n\n- [ ] 更加灵活的 props 操作","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsymphony09%2Frunning","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsymphony09%2Frunning","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsymphony09%2Frunning/lists"}