From 2d69b222e4efa83d9870d31c14becc74a7f02f9d Mon Sep 17 00:00:00 2001 From: xiehan <52160700+Barenboim@users.noreply.github.com> Date: Wed, 3 Jul 2024 23:12:26 +0800 Subject: [PATCH] Enable canceling graph node's successors. (#1583) * Enable canceling graph node's successors. * Update tutorial-11-graph_task.md * Update tutorial-11-graph_task.md --- docs/en/tutorial-11-graph_task.md | 23 +++++++++++++++++++++++ docs/tutorial-11-graph_task.md | 24 ++++++++++++++++++++++++ src/factory/WFGraphTask.cc | 6 ++++++ 3 files changed, 53 insertions(+) diff --git a/docs/en/tutorial-11-graph_task.md b/docs/en/tutorial-11-graph_task.md index b64f5908..d533e7ca 100644 --- a/docs/en/tutorial-11-graph_task.md +++ b/docs/en/tutorial-11-graph_task.md @@ -84,6 +84,29 @@ Also, any of the following codes is legal and equivalent: } ~~~ +# Canceling successors + +In graph tasks, we extend SeriesWork's **cancel** operation. When the series of a graph node is canceled, the operation will apply on all it's successive nodes recursively. The **cancel** operation is usually used in a task's callback: +~~~cpp +int main() +{ + WFGraphTask *graph = WFTaskFactory::create_graph_task(graph_callback); + WFHttpTask *task = WFTaskFactory::create_http_task(url, 0, 0, [](WFHttpTask *t){ + if (t->get_state() != WFT_STATE_SUCCESS) + series_of(t)->cancel(); + }); + WFGraphNode& a = graph->create_graph_node(task); + WFGraphNode& b = ...; + WFGraphNode& c = ...; + WFGraphNode& d = ...; + a-->b-->c; + b-->d; + graph->start(); + ... +} +~~~ +In this case, when http task failed, nodes b, c, d will all be canceled, because the operation is recursive. + # Data passing Because the tasks in a graph don't share a same series, there is no general method for passing data between graph nodes. diff --git a/docs/tutorial-11-graph_task.md b/docs/tutorial-11-graph_task.md index 96159436..dd972b98 100644 --- a/docs/tutorial-11-graph_task.md +++ b/docs/tutorial-11-graph_task.md @@ -85,6 +85,30 @@ WFGraphTask的create_graph_node接口,产生一个图节点并返回节点的 接下来直接运行graph,或者把graph放入任务流中就可以运行啦,和一般的任务没有区别。 当然,把一个图任务变成另一个图的节点,也是完全正确的行为。 +# 取消后继节点 + +在图任务里,我们扩展了series的cancel操作,这个操作会取消该节点的所有后继结点。 +取消操作一般在节点任务的callback里执行,例如: +~~~cpp +int main() +{ + WFGraphTask *graph = WFTaskFactory::create_graph_task(graph_callback); + WFHttpTask *task = WFTaskFactory::create_http_task(url, 0, 0, [](WFHttpTask *t){ + if (t->get_state() != WFT_STATE_SUCCESS) + series_of(t)->cancel(); + }); + WFGraphNode& a = graph->create_graph_node(task); + WFGraphNode& b = ...; + WFGraphNode& c = ...; + WFGraphNode& d = ...; + a-->b-->c; + b-->d; + graph->start(); + ... +} +~~~ +注意取消后继节点的操作是递归的,这个例子里,如果http任务失败,b,c,d三个节点的任务都会被取消。 + # 数据传递 图节点之间目前没有统一的数据传递方法,它们并不共享某一个series。因此,节点间数据传递需要用户解决。 diff --git a/src/factory/WFGraphTask.cc b/src/factory/WFGraphTask.cc index c51c28d2..3332a7a3 100644 --- a/src/factory/WFGraphTask.cc +++ b/src/factory/WFGraphTask.cc @@ -39,6 +39,12 @@ WFGraphNode::~WFGraphNode() { if (this->user_data) { + if (series_of(this)->is_canceled()) + { + for (WFGraphNode *node : this->successors) + series_of(node)->SeriesWork::cancel(); + } + for (WFGraphNode *node : this->successors) node->WFCounterTask::count(); }