{"id":18345732,"url":"https://github.com/hyperf/dag","last_synced_at":"2025-09-09T06:23:54.139Z","repository":{"id":51322582,"uuid":"367592091","full_name":"hyperf/dag","owner":"hyperf","description":"Directed Acyclic Graph","archived":false,"fork":false,"pushed_at":"2024-09-25T03:32:33.000Z","size":22,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"2.2","last_synced_at":"2024-10-30T16:45:03.330Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","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/hyperf.png","metadata":{"files":{"readme":"README.md","changelog":null,"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},"funding":{"open_collective":"hyperf","custom":"https://hyperf.wiki/#/zh-cn/donate"}},"created_at":"2021-05-15T09:38:04.000Z","updated_at":"2023-11-11T04:52:55.000Z","dependencies_parsed_at":"2023-02-01T05:15:45.443Z","dependency_job_id":"4920269b-3d54-4444-93f0-3ce2e5cf4560","html_url":"https://github.com/hyperf/dag","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fdag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fdag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fdag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fdag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperf","download_url":"https://codeload.github.com/hyperf/dag/tar.gz/refs/heads/2.2","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223245061,"owners_count":17112572,"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","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":[],"created_at":"2024-11-05T21:09:18.260Z","updated_at":"2024-11-05T21:09:19.173Z","avatar_url":"https://github.com/hyperf.png","language":"PHP","readme":"`hyperf/dag` 是一个轻量级有向无环图 (**D**irected **A**cyclic **G**raph) 任务编排库。\n\n## 场景\n\n假设我们有一系列任务需要执行。\n\n- 如果他们之间存在依赖关系，则可以将他们顺序执行。\n- 如果他们并不相互依赖，那么我们可以选择并发执行，以加快执行速度。\n- 两者间还存在中间状态：一部分任务存在依赖关系，而另一些任务又可以并发执行。\n\n我们可以将第三种复杂的场景抽象成 `DAG` 来解决。\n\n## 示例\n\n[![](https://mermaid.ink/img/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBBXG4gICAgQSAtLT4gQlxuICAgIEEgLS0-IENcbiAgICBBIC0tPiBEXG4gICAgRCAtLT4gR1xuICAgIEMgLS0-IEdcbiAgICBDIC0tPiBGXG4gICAgQiAtLT4gRlxuICAgIEIgLS0-IEVcbiAgICBCIC0tPiBIXG4gICAgSCAtLT4gSVxuICAgIEUgLS0-IElcbiAgICBGIC0tPiBJXG4gICAgRyAtLT4gSVxuICAgIEkgLS0-IFsqXVxuICAgICAgICAgICAgIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBBXG4gICAgQSAtLT4gQlxuICAgIEEgLS0-IENcbiAgICBBIC0tPiBEXG4gICAgRCAtLT4gR1xuICAgIEMgLS0-IEdcbiAgICBDIC0tPiBGXG4gICAgQiAtLT4gRlxuICAgIEIgLS0-IEVcbiAgICBCIC0tPiBIXG4gICAgSCAtLT4gSVxuICAgIEUgLS0-IElcbiAgICBGIC0tPiBJXG4gICAgRyAtLT4gSVxuICAgIEkgLS0-IFsqXVxuICAgICAgICAgICAgIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9)\n\n假设我们有一系列任务，拓扑结构如上图所示，顶点代表任务，边缘代表依赖关系。(A完成后才能完成B、C、D，B完成后才能完成H、E、F...)\n\n通过 `hyperf/dag` 可以使用如下方式构建 `DAG` 并执行。\n\n```php\n\u003c?php\n$dag = new \\Hyperf\\Dag\\Dag();\n$a = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"A\\n\";});\n$b = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"B\\n\";});\n$c = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"C\\n\";});\n$d = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"D\\n\";});\n$e = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"E\\n\";});\n$f = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"F\\n\";});\n$g = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"G\\n\";});\n$h = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"H\\n\";});\n$i = \\Hyperf\\Dag\\Vertex::make(function() {sleep(1); echo \"I\\n\";});\n$dag-\u003eaddVertex($a)\n    -\u003eaddVertex($b)\n    -\u003eaddVertex($c)\n    -\u003eaddVertex($d)\n    -\u003eaddVertex($e)\n    -\u003eaddVertex($f)\n    -\u003eaddVertex($g)\n    -\u003eaddVertex($h)\n    -\u003eaddVertex($i)\n    -\u003eaddEdge($a, $b)\n    -\u003eaddEdge($a, $c)\n    -\u003eaddEdge($a, $d)\n    -\u003eaddEdge($b, $h)\n    -\u003eaddEdge($b, $e)\n    -\u003eaddEdge($b, $f)\n    -\u003eaddEdge($c, $f)\n    -\u003eaddEdge($c, $g)\n    -\u003eaddEdge($d, $g)\n    -\u003eaddEdge($h, $i)\n    -\u003eaddEdge($e, $i)\n    -\u003eaddEdge($f, $i)\n    -\u003eaddEdge($g, $i);\n    \n// 需要在协程环境下执行\n$dag-\u003erun(); \n\n```\n\n输出：\n\n```php\n// 1s 后\nA\n// 2s 后\nD\nC\nB\n// 3s 后\nG\nF\nE\nH\n// 4s 后\nI\n```\n\n\u003e DAG 会按照尽可能早的原则调度任务。尝试将 B 点的耗时调整为 2 秒，会发现 B 和 G 一起完成。\n\n## 访问前步结果\n\n每一个任务可以接收一个数组参数，数组中包含所有前置依赖的结果。`DAG` 执行完毕后，也会返回一个同样结构的数组，包含每一步的执行结果。\n\n```php\n\u003c?php\n$dag = new \\Hyperf\\Dag\\Dag();\n$a = \\Hyperf\\Dag\\Vertex::make(function() {return 1;});\n$b = \\Hyperf\\Dag\\Vertex::make(function($results) use ($a) {\n    return $results[$a-\u003ekey] + 1;\n});\n$results = $dag-\u003eaddVertex($a)-\u003eaddVertex($b)-\u003eaddEdge($a, $b)-\u003erun();\nassert($results[$a-\u003ekey] === 1);\nassert($results[$b-\u003ekey] === 2);\n```\n\n## 定义一个任务\n\n在上述文档中，我们使用了闭包来定义一个任务。格式如下。\n\n```php\n// Vertex::make 的第二个参数为可选参数，作为 vertex 的 key，也就是结果数组的键值。\n\\Hyperf\\Dag\\Vertex::make(function() { return 'hello'; }, \"greeting\");\n```\n\n除了使用闭包函数定义任务外，还可以使用实现了 `\\Hyperf\\Dag\\Runner` 接口的类来定义，并通过 `Vertex::of` 将其转化为一个顶点。\n\n```php\nclass MyJob implements \\Hyperf\\Dag\\Runner {\n    public function run($results = []) {\n        return 'hello';\n    }\n}\n\n\\Hyperf\\Dag\\Vertex::of(new MyJob(), \"greeting\");\n```\n\n`\\Hyperf\\Dag\\Dag` 本身也实现了 `\\Hyperf\\Dag\\Runner` 接口，所以可以嵌套使用。\n\n```php\n\u003c?php\n// 命名空间已省略\n$a = Vertex::make(function () { return 1;});\n$b = Vertex::make(function () { return 2;});\n$c = Vertex::make(function () { return 3;});\n\n$nestedDag = new Dag();\n$nestedDag-\u003eaddVertex($a)-\u003eaddVertex($b)-\u003eaddEdge($a, $b);\n$d = Vertex::of($nestedDag);\n\n$superDag = new Dag();\n$superDag-\u003eaddVertex($c)-\u003eaddVertex($d)-\u003eaddEdge($c, $d);\n$superDag-\u003erun();\n```\n\n## 控制并发数\n`\\Hyperf\\Dag\\Dag` 类提供了 `setConcurrency(int n)` 方法控制最大并发数。默认为10。\n","funding_links":["https://opencollective.com/hyperf","https://hyperf.wiki/#/zh-cn/donate"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperf%2Fdag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperf%2Fdag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperf%2Fdag/lists"}