Go实战 | 基于有向无环图的并发执行流的实现

本文介绍了如何使用有向无环图(DAG)实现并发执行的工作流,以穿衣服流程为例,详细阐述了节点、边的定义,以及开始节点、结束节点的构建。工作流的执行通过检查依赖边是否完成,实现了并发和顺序执行的混合,适用于程序化广告等场景。
摘要由CSDN通过智能技术生成

大家好,我是「Go学堂」的渔夫子。今天跟大家聊聊基于有向无环图的工作流的实现。

01 工作流(workflow)概述

工作流,是对工作流程中的工作按一定的规则组织在一起并按其进行执行的一种模型。比如常见的行政系统中的加班申请、请假申请;工作流要解决的问题就是为了实现某个特定的目标,让多个参与者之间按某种预订的规则自动的传递信息。

本文介绍了一种基于有向无环图实现的工作流,通过有向无环图,可以解决两个问题:从逻辑上,对各个节点的依赖关系进行了组织;从技术上,有依赖关系的节点需要等待执行,无依赖关系的可以并发执行。

该工作流的实际应用是在程序化广告中从接收请求到广告响应之间的流程:接收请求、获取地理位置、获取用户画像、广告召回、广告排序、算法预估、返回响应等各个节点之间的依赖执行。

但本文的目标是介绍其实现思想,所以在示例部分会以穿衣服的流程为例进行讲解。

02 工作流的实现

下面我们以早上起床穿衣所发生的事件为例来讲解有向无环图的实现。穿衣流程中包含的事件有穿内裤、穿裤子、穿袜子、穿鞋、戴手表、穿衬衣、穿外套等。这些事件中有的必须要先穿某些衣服,才能再穿其他衣服(如先穿袜子后才能穿鞋)。有些事件则可以以任意顺序穿上(如袜子和裤子之间可以以任意词序进行穿戴)。如图所示:

 

由上图可以看到,穿内裤、穿袜子、穿衬衣、戴手表之间没有相互依赖,可以并发执行。而穿鞋子则必须等待所依赖的裤子和袜子穿完后才能执行。下面我们就来看看如何实现这样的有向无环图的工作流。

2.1 定义工作流结构

根据上图,我们可以看出一个相对完整的工作流包含开始节点(从哪里开始)、边(经过哪些节点)、结束节点(到哪里结束)。由此,我们定义工作流的结构如下:

type WorkFlow struct {
    done chan struct{} //结束标识,该标识由结束节点写入
    doneOnce *sync.Once //保证并发时只写入一次
    alreadyDone bool //有节点出错时终止流程标记
    root *Node //开始节点
    End *Node //结束节点
    edges []*Edge //所有经过的边,边连接了节点
}
复制代码

2.2 定义工作流中边

边用来表示两个节点之间的依赖关系。有向图中的边还能表明两个节点哪个是前置节点,哪个是后置节点。后置节点需要等待前置节点的任务执行完成后才能执行。如下图所示:

 

内裤和裤子两个节点说明只有等穿上内裤后,才能穿裤子,那么穿内裤节点就是穿裤子节点的前置节点;而鞋子只有等裤子和袜子都穿上后才能穿鞋子,那么裤子和袜子就是鞋子的前置节点。

所以边的表示是从哪个节点到哪个节点。定义如下:

type Edge struct {
    FromNode *Node
    ToNode *Node
}
复制代码

2.3 定义工作流中的节点

节点即要具体执行逻辑的任务单元。同时每个节点都有所关联的边。因为我们使用的是有向图,所以关联的边又分为入边(即终止于该顶点的边)和出边(即从该顶点开始的边)。如下图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

渔夫子@Go学堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值