首页> 中国专利> 一种有向无环图式自动任务流的通用描述语言数据系统

一种有向无环图式自动任务流的通用描述语言数据系统

摘要

本发明提供一种有向无环图式自动任务流的通用描述语言数据系统,包括:Step定义层,Workflow定义层和Template定义层;Step层为单个任务的描述,针对一个docker镜像或其他执行器的输入输出声明,需要具体声明每个输入输出项的名称,类型,文档,参数等信息;Workflow层为一个或多个Step组成的工作流,需要定义这些Step的依赖拓扑,还可以定义共享参数;Template层在一个Workflow定义的基础上,模板进行参数的预设置,以及补充参数的说明、检查器或数据源定义。本发明数据中心与任务执行工具进行使用,需要使用编程语言实现对应工具。数据中心需要能够存储每个定义文档,并且通过引用链接索引到对应的文档,解释器需要读取所有定义内容,并根据引用链接将对应数据赋值到定义结构中。

著录项

  • 公开/公告号CN112162737A

    专利类型发明专利

  • 公开/公告日2021-01-01

    原文格式PDF

  • 申请/专利权人 深圳晶泰科技有限公司;

    申请/专利号CN202011091614.7

  • 申请日2020-10-13

  • 分类号G06F8/30(20180101);

  • 代理机构44248 深圳市科吉华烽知识产权事务所(普通合伙);

  • 代理人胡吉科

  • 地址 518000 广东省深圳市龙华区大浪街道新石社区华联工业区9号4层

  • 入库时间 2023-06-19 09:24:30

说明书

技术领域

本发明属于云计算领域,特别涉及一种有向无环图式自动任务流的通用描述语言数据系统。

背景技术

现今科学计算领域中专业细分化趋势明显,细化的解决问题算法的发展与实际价值导向的工程运用已分化为发展的两个方向。如何结合运用细分的专业方法完成目标成为了一个必不可少的需求,越来越小的方法粒度也使得了解大量方法的学习成本与使其结合的人工成本越来越高,自动化的工作流这一技术也在各个领域得以广泛应用。在科学计算领域:美国的SBG(Seven Bridges Genomics)公司开发的SBP(Seven Bridge Platform)被视作为公司核心技术,它集成了算法,数据托管,计算资源于一体,通过可视化的界面构建出灵活的基因组数据分析流程并执行计算;在开源界也有通用化的任务流描述语言标准CWL(Common Workflow Language),主要针对于数据密集型科学计算,通过文本格式的任务流描述与命令行工具串联不同的任务执行,主流的云计算资源提供商如AWS、Google,AliCloud,计算标准如HPC,Spark等均为CWL提供了支持。

对于任务流描述语言,核心功能有两点:定义具体任务与定义任务间流转。通过定义具体的任务来描述任务的输入输出与执行方式,通过定义任务间流转来定义任务执行的顺序与数据流转的路径,这些核心信息提供给具体的任务流引擎进行解析,就可以完成任务流的自动化执行。

对于封闭式的任务流平台,他缺乏开放性与易用性,仅可以使用内部已提供的算法任务进行编排,难以满足快速发展的计算需求,并且无法接入灵活的计算资源,故我们主要关注与通用的任务流描述语言。

对于现有的通用描述语言来说,主要有以下缺陷:

1、任务描述粒度粗糙:

现有的通用描述语言的单个任务描述粒度十分粗糙,用户需要定义输入的参数组以及获取方式,但语言并不涉及数据的类型与细节结构,使得用户在使用时需要深度了解任务的具体特性,在提供了错误的数据类型、结构是也无法提供数据检查与校验。

2、计算机领域知识门槛高,不便非计算机专业人员编排:

现有的通用描述语言与计算机编程技术紧密耦合,暴露出了大量的底层细节与计算机专有名词,用户需要拥有一定的计算机领域知识才能进行编写。不能满足算法编写人员(计算机工程师)与算法使用人员(科学家)同时使用的需求。

3、信息庞杂,缺乏数据复用

现有的通用描述语言在应用于高性能科学计算时,由于其通用性,需要定义大量的科学计算领域特点所带来的参数,并且参数需要反复重复输入,没有数据模板与数据覆盖填充能力

4、缺乏自动并行源语

在科学计算领域,由于庞大的计算需求,并行是一种不可或缺的能力。现有的通用描述语言缺乏类似map-reduce或scatter-gather的并行描述原语,无法提供对于单点任务自动并行的功能。

发明内容

基于此,有必要提供一种有向无环图式自动任务流的通用描述语言数据系统,包括:

Step定义层,Workflow定义层和Template定义层;

Step层为单个任务的描述,针对一个 docker 镜像或其他执行器的输入输出声明,需要具体声明每个输入输出项的名称,类型,文档,参数等信息;

Workflow层为一个或多个 Step 组成的工作流,需要定义这些 Step 的依赖拓扑,还可以定义共享参数;

Template层在一个 Workflow 定义的基础上,模板进行参数的预设置,以及补充参数的说明、检查器或数据源定义。

本发明采用以上技术方案,通过TypeDef定义自定义类型,TypeDef支持多个关键字如type, required, symbols, value, const, ref, embed_value等,通过这些关键字扩展数据的细节来提升数据描述粒度。而描述单个任务的Step定义在inputs,outputs声明中引用不同的TypeDef来声明自己的输入输出,实现高精度的完善的任务描述。解决现有的通用描述语言的单个任务描述粒度十分粗糙的问题。

Workflow构建Template的具体步骤:解析Template中的values项,values项会包含$step2/$in_arg2: {const: 1.0}这样的数据,第一个字段斜杠前为step名称,斜杠后为输入项名称,通过这两个参数定位Workflow中具体的映射。第二个字段,冒号前的第一个参数表明数据性质,示例中该数据为常量,后一个参数为具体数据。应用Template时将第二个参数表示的性质与数据覆盖到第一个参数表示的step名称与输入项名称中即可。

各层级之间的引用均通过url实现,例如(type: ^typedef/common/version/1.0.0)即为表示该变量的类型引入一个名为common版本为1.0.0的TypeDef定义,通过像数据中心请求这些参数获取定义的原文。

优选的,还包括TypeDef层,如果用户需要使用特殊的自定义类型,则需要编写TypeDef层,这一部分主要是将通用的、或者复杂的复合类型的定义进行抽象,方便引用也方便管理。

本发明进一步采用以上技术方案,其优点在于,TypeDef中的required, type,value, const, serizalier, symbols等关键字除了提供类型声明之外,还支持默认值,常量,枚举值等详细声明。通过对输入数据与这些声明的匹配,可以实现更加精细的数据检查与校验。从而做到提供数据检查和校验的。

本发明还提供实现该四层定义间的数据的引用的方案,包括:

1、Step仅会引用TypeDef,通过在定义数据的type时填写引用url实现,如:

inputs:

$in_arg1:

type:^typedef/common/jobArgs/version/1.0.0

表示该Step引用了名为common的TypeDef定义中名为jobArgs的类型定义

2、Workflow仅会引用Step,通过在声明所用Step的run字段时填写url实现,如:

steps:

$step1:

run: ^step/demo/version/1.0.0

表示该Workflow引用了一个名为demo的版本为1.0.0的step定义

Template仅会引用Workflow,通过在元数据中声明的workflow字段里填写url实现,如:

workflow:^workflow/some_workflow/version/1.0.0

表示该Template应用于名为some_workflow的Workflow定义。

相应的,本发明还提供一种采用所述的系统的解析方法,包括如下几个步骤:

递归分析:将输入文档以及输入文档依赖的所有文档从数据中心拉取到本地。解析器会递归遍历第一个输入文档的每个值,若为^开头的外部链接,则将该链接通过数据中心Client下载到对应的文件,并对新文件重复该步骤,直至所有依赖链接都准备完毕。

语法树分析:由于描述语言的每一层数值都拥有优先级与覆盖关系,所以为了实现层层覆盖的数据逻辑,需要从最底层开始逐层构建并应用覆盖;

解析Template文件,遍历Template中的具体的变量与值,索引到Workflow对象中的某个Step的某个输入输出值进行覆盖运算。

对象装载: 解析完毕后将得到一棵对象形式的树,workflow对象为根节点,workflow通过steps属性包含了所有的Step对象,Step对象通过inputs/outputs属性包含了所有的TypeDefs对象;

除了构建层级明确的对象树与层级赋值之外,解析器第二个重要的算法是对Workflow进行拓扑排序。用户定义了不同Step之间的依赖,拓扑排序算法可以求解出Step最高效的运行解决方案。

优选的,所述解析方法包括:

第一层解析的为Class为TypeDef的类型定义文件,通过文件内容构建所有TypeDef的对象并作为K:V映射存在内存中。

第二层构建Step对象,解析所有class为Step的文件。通过文件内容构建出Step对象,Step对象的inputs/outputs属性包含了若干TypeDef对象,若Step应用了自定义类型的变量,则从TypeDef K:V映射中取到已加载好的对象替换Step中的该对象,并进行值覆盖运算。

第三层构建Workflow对象,解析class为Workflow的文件,通过文件内容构建出Workflow对象,Workflow对象的steps属性包含了所有该workflow涉及的Step,以StepName: StepObject的映射方式存储。Workflow从Step映射中取到所有自己依赖的Step对象存入自己的steps属性中,并根据文件内容将workflow定义中的值与Step对象中的值进行覆盖运算。

优选的,所述拓扑排序算法的方法包括如下几个步骤:

步骤A:通过每个Step的inputs中标注的ref链接,求出一个FollowMap,FollowMap为一个<被依赖Step: 依赖Step>列表的映射;

步骤B:得到FollowMap之后,将FollowMap映射倒置,得到LeaderMap,也就是 的映射;

步骤C:引入Distance概念,流程图中简写为Dis,意为与被运行的依赖距离,默认为1;

步骤D:遍历所有step,若该Step还未被检查,遍历该Step的LeaderSteps,若一个Step没有Leader,则说明该Step无依赖,视为已检查并置Dis为1;而其他Step中LeaderMap有依赖的,该Step的Dis均加上其LeaderSteps的Dis,以此类推。

通过在Step的inputs中声明连接各Step间的拓扑依赖,该递归思想的核心借鉴了数学上图的拓扑排序算法,FollowMap,LeaderMap为邻接矩阵的一种表现形式。通过LeaderMap确定起点,通过Dis这一概念将起点Step置为1,中间点Step的Dis均为从起点连同到该点的途径Step的Dis之和。通过对Dis进行排序我们即可得到最高效率的运行顺序。且当某个Step执行完毕,我们只需要根据FollowMap递归减去后续节点的Dis,即可更新为当前状态的运行顺序。

本发明进一步采用以上技术方案,解决了需要定义大量的科学计算领域特点带来的参数问题和解决数据模板和数据覆盖填充能力的问题。

本发明带来了如下有益效果:

1.输入输出描述详细:详细描述了通过检查type关键字是否完全相同实现输入与输出的匹配。

2、通过ref关键字指定输入项的数据来源为某一输出项(如Workflow示例中 $arg1: {ref: $step1/$output_list1} 表示输入项arg1链接step1的名为output_list1的输出项)实现类型与数值,支持自定义类型,

3、通过TypeAndValueDefine子结构包含的doc关键字实现,doc关键字可以附加描述信息,仅作为注释展示,不进行解析计算 附加与计算无关的说明文字,并可以基于类型信息提供具体的输入检测与数据转换。

4、 通过四层结构分离实现了领域知识的解耦,在使用场景中,计算机领域专业人员编写typeDef定义,科学计算领域专业人员编写Step定义,并引用Step定义编写Workflow定义,任务运行专业人员组合使用Workflow定义,并根据提交经验总结编写Template定义,得到了领域知识解耦:单个任务与工作流编排完全解耦,无需了解计算机相关知识与具体算法任务细节,只要任务定义的输入输出类型可以匹配,便可以编排连接。

5、自动并发原语:通过scatter_gather关键字声明具体的分发参数,将输入的数据列表依照分发参数拆分为若干个数据组,创建多个子任务并将每个数据组分发给每一个子任务进行并行计算支持scatter-gather自动并发子任务的声明,

6、自动并发子任务提供的并行能力使得该描述语言定义的工作流可以应用在计算加速,数据分析,流式计算等多个场景。不再局限于单一的提供输入输出进行计算的简单描述。并且加强了领域解耦能力,算法专家聚焦于解决抽象问题进行开发,对于并行能力这种计算机领域的概念无需顾及,当实际计算问题需要批量并行处理时由该描述语言满足这一能力,扩展了任务的使用方式与能力

7.数据模板应用,数据覆盖传到:四层定义间的数据均存在引用关系,可以根据层级优先进行覆盖,并可以应用不同的数据模板实现一键配置或默认参数配置。

本发明仅为一套语言标准,该语言提供了所有必要信息的定义,而具体执行任务需要配合解释器,数据中心与任务执行工具进行使用,需要使用编程语言实现对应工具。数据中心需要能够存储每个定义文档,并且通过引用链接索引到对应的文档,解释器需要读取所有定义内容,并根据引用链接将对应数据赋值到定义结构中。任务执行工具需要通过解释器得到的完整结构化数据,遵循这些信息调度提交任务。

附图说明

图1本发明中数据系统中语言的具体层级结构与引用关系。

图2本发明中数据系统中语言的数据模板覆盖。

图3本发明中数据系统中语言的具体使用流程。

图4展示了数据中心上传下载的工作流程。

图5展示了主要的解析流程。

图6展示了拓扑排序算法的主要思路。

具体实施方式

实施例1

图1说明该语言的具体层级结构与引用关系。通过四大层级进行工作流的具体描述,分别为TypeDef定义层,Step定义层,Workflow定义层与Template定义层。以下为每个定义层的示例与介绍:

TypeDef层不是必须的,如果用户需要使用特殊的自定义类型,则需要编写TypeDef层,这一部分主要是将通用的、或者复杂的复合类型的定义进行抽象,方便引用也方便管理;Step层为单个任务的描述,针对一个 docker 镜像或其他执行器的输入输出声明,需要具体声明每个输入输出项的名称,类型,文档,参数等信息;Workflow层为一个或多个 Step组成的工作流,需要定义这些 Step 的依赖拓扑,还可以定义共享参数;Template层需要在一个 Workflow 定义的基础上,模板可以进行参数的预设置,以及补充参数的说明、检查器或数据源定义。一个模板必须显式声明一个唯一的Workflow;各层级之间的引用均通过url实现,例如(type: ^typedef/common/version/1.0.0)即为表示该变量的类型引入一个名为common版本为1.0.0的TypeDef定义。

实施例2

xwlVersion描述了该描述语言的版本,用于区分随着功能的不断加入带来的版本迭代;class描述了这个文档的类型,共有(TypeDef,Step,Workflow,Template)四种;version描述该定义的版本;author描述了作者的信息;doc描述了对于该文档的注释说明;name描述了该文档的名称,相同类型的文档在编写时作者需要保持命名唯一性;

在描述语言中定义了名为TypeAndValueDefine的子结构,它包含了类型,名称,值以及若干属性,用于详细定义一个变量。以下为三个较有代表性的TypeAndValueDefine的示例:

$name:

type: int[]

const: 1

value: 1

ref: $xxx/$xxx

required: true

doc: this is a type and value defing demo

symbols: [1, 2, 3]

$oneDir:

type: dir

autoSyncInterval: 300 自动上传的时间间隔(单位s)

autoSyncIgnore: ["run_charm_[0-9]*/", "calc[0-9]*/"]

$oneObject:

type: object

serializer: # obj对象类型需要定义编解码器

saveType: file

fileExt: json

encoder: ^py:json.dumps

decoder: ^py:json.loads

具体步骤为:

第一步:在最外层定义子结构的名称,最外层的$name为该子结构的名称,遵循语言原则以$开头;

第二步:定义所需的描述子结构属性的通用关键字: type关键字为类型描述,支持int, double, boolean, string, array, file, dir, dict, record, obj这些结构,并可以通过添加[]后缀标识为列表;const与value为互斥的关键字,表明该子结构定义代表的值,value为可变值,const为不可变值;ref为与value/const互斥的关键字,标识该值来源引用与一个其他的TypeAndValueDefine子结构;required关键字为该定义是否必须有值,默认为true;doc关键字为描述说明;symbols关键字为枚举值域,在定义需要限定值域时使用;

第三步:定义描述子结构在特定类型时支持的特殊关键字:

如在第二个定义中该子结构为一个类型为文件夹的定义。可以定义autoSyncInterval关键字为自动同步的时间间隔;autoSyncIgnore关键字为默认忽略的文件名列表,支持正则语法;

如在第三个定义中该子结构为一个类型为自定义对象的定义。可以定义serializer关键字为对象定义所需要的编解码器定义;saveType关键字为存储方式,可以为file/string;fileExt为存储文件的后缀名,当saveType为file时使用;encoder关键字为编码器url,链接到的编码器需要是一个可执行的方法,接受一个对象,返回字符串数据;decoder关键字为解码器url,连接到的解码器需要时一个可执行的方法,接受一个字符串数据,返回一个对象。编解码器遵循外部链接准则,使用^前缀,py:标识它为一个python方法。

实施例3

以下为一个名为common的TypeDef定义的例子(通用信息部分不再赘述):

xwlVersion: 1.0.0

class: TypeDef

doc: a stucture type def

author: ziqi.jiang

name: common

version: 1.0.0

typeDefs:

$jobArgs:

doc: Contains some info about compute args

type: record

fields:

:cores:

type: int

:memory:

type: int

具体步骤为:

第一步:在最外层定义typeDefs关键字,typeDefs关键字内部包含一些TypeAndValueDefine子结构。如该定义声明了一个名为struct的record数据,fields是record类型的子键声明,它包含两个个属性cores,memory;

第二步:在使用类型定义的TypeAndValueDefine子结构中通过固定格式的链接声明在type中,如下为一个使用了该typeDef的TypeAndValueDefine子结构:

$use_typedef_demo:

type: ^typedef/commmon/jobArgs/version/1.0.0。

实施例4

Step定义包含了对于一个计算任务的具体描述,以下为一个Step定义的示例(通用信息部分已忽略)

entryPoint: ^py:/home/job/run/loader.py

jobArgs:

type: ^typedef/common/jobArgs/version/1.0.0

value:

cores: 16

memory: 24000

inputs:

$in_arg1:

type: file

outputs:

$out_arg1:

type: double

第一步:定义描述该Step属性的四个主要关键字:entryPoint,jobArgs,inputs,outputs。entryPoint为该Step的执行入口,如例子中使用python执行的位于/home/job/run目录下的loader.py文件。jobArgs为Step的执行参数,例子中使用了引用的TypeDef,给出了16核24000MB的默认值;

第二步,定义输入输出项:inputs/outputs为该Step的输入输出参数列表,内部为若干个TypeAndValueDefine子结构;

实施例5

Workflow定义包含了若干个Step声明以及Step之间的参数依赖关系,一下为一个Workflow定义的示例(已省略通用信息部分):

vars:

$share_arg1:

type: string

steps:

$step1:

run: ^step/demo/version/1.0.0

jobArgs:

cores: 2

memory: 3000

in:

$arg1:

ref: {vars/$share_args1}

out: [$output_list1, $output2]

$step2:

run: ^ step/scatter_gather_demo/version/1.0.0

scatter

maxJob: 100

minJob: 0

zip:

$scatter_in_arg1: {ref: $step1/$output_list1}

jobIn:

$in_arg1: {ref: zip/$item}

$in_arg2: ~

gather:

failTol: 0.1

retryLimit: 1

jobOut: [$output]

unzip:

$gather_outputs: {ref: jobOut/$output}

outputs:

$out_wf_arg1: {ref: $step2/gather_outputs}

具体步骤为:

第一步:在最外层定义所需重复使用的共享变量池vars:vars关键字为一组作用于为该文档内的共享变量定义池,若workflow中多个step需要共享一组输入时,可以通过ref关键字引用;step关键字为workflow所使用到的Step定义以及他们的依赖拓扑,内部以step名称,step定义的键值对声明;

第二步:定义所使用的Steps以及他们的拓扑关系:

以steps关键字下有两个名为step1,step2的step声明:

在step1的声明中,run为该step的具体定义url,用遵循准则的^开头的外部链接表示,意为引入名为demo的1.0.0版本定义;jobArgs关键字映射于Step中定义的jobArgs,在这里为它赋予了一个默认值;in关键字为声明的输入参数,在这里声明了一个名为arg1的参数的值引用自共享变量中share_arg1的值,in中的命名需要与Step定义中inputs内输入项的名称保持一致;out关键字为在该workflow中启用的参数,其中的名称需要与Step定义中outputs内输出项的名称保持一致。

在step2的声明中,展示了一个使用scatter-gather原语所声明的自动并发step。jobArgs在不赋予默认值时可以省略;scatter关键字声明这是一个并发的step;

scatter关键词会将接收到的输入列表中的每一个元素通过zip映射分发到与输入列表数量相同的子任务中,在scatter定义下:maxJob/minJob关键字为该任务并发的数量范围;zip为该任务并发的批量参数映射,zip下为若干个TypeAndValueDefine子结构,由于任务定义时面向单一输入,所以需要定义一个参数映射来表明接收到的多个参数如何映射到需要并发的子任务输入项中。如这个例子声明了一个名为scatter_in_arg1的数组类型,它承接了step1任务名为output_list1的结果;jobIn关键字为该step的原始输入,内部为若干个TypeAndValueDefine子结构,名称必须与Step定义inputs输入项名称保持一致,如这里的in_args1就声明了值来自于zip映射内的scatter_in_arg1。意为当运行时会将scatter_in_arg1接收到的list中的每个元素分发到每个子job的in_arg1项上。

gather关键词会将多个子任务输出的结果通过unzip映射聚合为输出列表,在gather定义下:failTol为子job的失败容错率,为0-1范围内的小数,若失败任务占比大于该小数,则认为该step失败,放弃重试;retryLimit为允许的最大失败重试次数,若有部分子任务失败且失败数量占比小于容错率,则会重试不超过retryLimit次;jobOut为启用的原Step定义中的output项,名称需要与Step定义中输出项保持一致;unzip为参数聚合的映射,如该例子中,unzip声明了一个名为gather_outputs的定义聚合了所有子任务的outputs项;

最外层的outputs关键字,意为该workflow的最终输出,如该例子中,定义了一个名为out_wf_arg1的输出,它的值来源于step2的聚合结果gather_outputs。

实施例6

Template定义用于指定一组预置的值作为数据模板应用在workflow上。以下为一个Template定义的示例:

workflow: ^workflow/some_workflow/version/1.0.0

values:

vars/$share_arg1: {value: 233}

$step2/$in_arg2: {const: 1.0}

具体步骤为:

第一步:定义该Template所应用的目标Workflow关键字:workflow为该Template所要应用到的workflow定义url

第二步:定义对于该Workflow预填充的值values:values用于固定一些需要填充的值,仅支持value/const两种形式的数据,如以上例子中,分别填充了共享变量vars中名为share_args1的定义值为可变值233,以及step2输入中名为in_arg2的定义值为不可变值1.0。

图2说明该语言的数据模板覆盖,解析行为表。数据基于性质分为value(可变值)与const(不可变常量)两种,基于来源分为:typedef,step,workflow,template,inline五种。当一个Workflow被执行时,需要从多层定义的数据源中解析出最终数据,当一个定义拥有多个数据源时,会发生忽略,覆盖,冲突三种行为。数据的解析遵循以下原则:const数据无法被覆盖;inline > template> workflow > step > typeDef;两个value相遇按优先级覆盖(inlineValue可覆盖inlineValue);两个const相遇冲突;高层value遇到低层const冲突。

图3说明该语言的具体使用流程。在编写使用本语言时:计算机工程师需要将已有算法通过该语言的Step定义进行描述。首先根据已有算法需求编写可能需要的自定义类型定义TypeDef并发布到数据中心,然后编写描述该已有算法的Step定义并发布,若需要使用则通过url引用自定义TypeDef。科学计算解决方案专家编写Workflow定义,在Workflow定义中通过引用url引用所需要的Step定义,并在Workflow中逐一将各Step的输出连接到下一Step的输入上进行编排。最后编写Template定义对于具体使用方案的默认值进行填充。任务执行者只需要选取对应的Workflow与模板,传入该语言解释器,该语言解释器将自顶向下逐层解析并从数据中心通过引用url获取对应的数据进行解析,最后将解析过的完整数据传递至任务执行工具进行任务提交。

实施例7

发布Step定义的具体流程如下:

数据中心:

数据中心为简单C/S架构的服务,通过Server端数据库管理索引,文件系统管理具体数据内容;Client端进行简单的解析与上传,下载工作。图4展示了数据中心上传下载的工作流程:

上传工作流程:

用户提交描述语言文件请求客户端。客户端读取文件内容,通过分析class, name,version字段获取具体的类型,名称,版本参数,携带文件内容请求服务端;服务端通过对应参数索引数据库,若已存在类型,名称,版本相同的文件则返回参数检查失败;若未存在则生成一个新的文件地址,同时将详细信息添加数据库。然后服务端访问文件系统将文件存储在新的文件地址,然后向客户端返回结果。

下载工作流程:

用户携带类型,名称,版本参数访问服务端;服务端通过对应参数索引数据库,若未存在返回NotFound错误,若存在则获取具体文件地址,通过文件地址访问文件系统并获取文件内容,向客户端返回结果。

采用以上方案,其优点在于,将文件使用文件系统存储而不直接存储入数据库既保留了数据的原始粒度,也保证了描述语言文件的完整性,将较大的文件使用文件系统也会提高数据库的性能,在批量请求文件时可以更快的索引地址并使用多线程加速文件读取。

解析器:

解析器是一个独立且离线的数据分析工具,主要通过递归分析,语法树分析,对象装载,应用链接,逐层应用数值等步骤解析完整的定义。图5展示了主要的解析流程:

在解析器开始解析内容之前,首先要将输入文档以及输入文档依赖的所有文档从数据中心拉取到本地。解析器会递归遍历第一个输入文档的每个值,若为^开头的外部链接,则将该链接通过数据中心Client下载到对应的文件,并对新文件重复该步骤,直至所有依赖链接都准备完毕。

由于描述语言的每一层数值都拥有优先级与覆盖关系,所以为了实现层层覆盖的数据逻辑,需要从最底层开始逐层构建并应用覆盖。第一个解析的为Class为TypeDef的类型定义文件,通过文件内容构建所有TypeDef的对象并作为K:V映射存在内存中。

第二层构建Step对象,解析所有class为Step的文件。通过文件内容构建出Step对象,Step对象的inputs/outputs属性包含了若干TypeDef对象,若Step应用了自定义类型的变量,则从TypeDef K:V映射中取到已加载好的对象替换Step中的该对象,并进行值覆盖运算。

第三层构建Workflow对象,解析class为Workflow的文件,通过文件内容构建出Workflow对象,Workflow对象的steps属性包含了所有该workflow涉及的Step,以StepName: StepObject的映射方式存储。Workflow从Step映射中取到所有自己依赖的Step对象存入自己的steps属性中,并根据文件内容将workflow定义中的值与Step对象中的值进行覆盖运算。

最后解析Template文件,遍历Template中的具体的变量与值,索引到Workflow对象中的某个Step的某个输入输出值进行覆盖运算。

解析完毕后将得到一棵对象形式的树,workflow对象为根节点,workflow通过steps属性包含了所有的Step对象,Step对象通过inputs/outputs属性包含了所有的TypeDefs对象。

除了构建层级明确的对象树与层级赋值之外,解析器第二个重要的算法是对Workflow进行拓扑排序。用户定义了不同Step之间的依赖,拓扑排序算法可以求解出Step最高效的运行解决方案。图6展示了拓扑排序算法的主要思路:

通过每个Step的inputs中标注的ref链接,求出一个FollowMap,FollowMap为一个<被依赖Step: 依赖Step>列表的映射

得到FollowMap之后,将FollowMap映射倒置,得到LeaderMap,也就是 的映射。

引入Distance概念,流程图中简写为Dis,意为与被运行的依赖距离,默认为1(可直接运行)

遍历所有step,若该Step还未被检查,遍历该Step的LeaderSteps,若一个Step没有Leader,则说明该Step无依赖,视为已检查并置Dis为1。而其他Step中LeaderMap有依赖的,该Step的Dis均加上其LeaderSteps的Dis,以此类推。

该递归思想的核心借鉴了数学上图的拓扑排序算法,FollowMap,LeaderMap为邻接矩阵的一种表现形式。通过LeaderMap确定起点,通过Dis这一概念将起点Step置为1,中间点Step的Dis均为从起点连同到该点的途径Step的Dis之和。通过对Dis进行排序我们即可得到最高效率的运行顺序。且当某个Step执行完毕,我们只需要根据FollowMap递归减去后续节点的Dis,即可更新为当前状态的运行顺序。

以上述依据本申请的理想实施例为启示,通过上述的说明内容,相关工作人员完全可以在不偏离本项申请技术思想的范围内,进行多样的变更以及修改。本项申请的技术性范围并不局限于说明书上的内容,必须要根据权利要求范围来确定其技术性范围。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号