技术领域
[0001] 本发明一般涉及工作流,尤其涉及允许元编程的最优增量工作流执行。
相关背景技术
[0002] 工作流系统表示过程管理技术的应用。工作流是定义过程或程序的操作方面的有组织的互相关任务集。具体而言,工作流可定义任务如何结构化、负责实体以及任务的相对排序等。因此,工作流方便过程的自动化设计、控制和监视。
[0003] 一种公知工作流是企业工作流,该企业工作流自动化业务过程以使得文档、信息和/或任务被传递至各个人以便根据程序规则来行动。例如,一个人可以按顺序执行某一指定工作,并且随后在完成时可启动其他人的工作。实际上,工作的传递基于先前任务的完成来自动化和控制。作为示例,贷款评估或批准过程可被表示为工作流。
[0004] 还能够在计算机系统及相关联的功能,而不是单独的人类相关任务的上下文中采用工作流。作为示例,可采用被称为构建系统(build system)的专用工作流系统来方便程序开发。
[0005] 构建系统使得能够像构建那样脚本化并执行各种各样的程序开发任务,包括将源代码编译成二进制代码、测试和开发,等等。虽然从命令提示中调用对单个文件的开发操作是容易的,但类似地对通常是具有复杂依赖关系的大量文件发起这些操作是呈指数地更加困难的。构建系统被设计成通过使开发者能够描述并且随后数次发起对各自具有特定功能的分立代码单元的一系列调用的执行来帮助该情形。例如,构建系统可允许在对一个或多个组件源文件作出改变时快速重新编译程序。
[0006] 具体而言,工作流和构建当前利用域专用语言或标记语言来指定。域专用语言(DSL)是被设计成在特定域中工作的专用语言。例如,经常采用允许非技术人员查看并操纵过程的图形DSL。诸如XML(可扩展标记语言)等标记语言是用于通过文本注释来表示结构化数据的数据描述语言。
具体实施方式
[0026] 以下细节一般涉及工作流,包括工作流的构造和执行。工作流可由通用程序来构造以利用通用编程语言的可表达性,包括特定语言特征或编码技术,诸如但不限于,继承、参数化和条件,以及与其相关联的常规工具,诸如调式器、类型校验器和代码优化器,等等。此外,可以例如执行元编程以观察、推理、修改和/或生成工作流。
[0027] 包括表示项目和任务的互相关节点集的通过程序构造的工作流能够从开始到结束增量式地执行。此外,项目和任务依赖关系能够在该工作流中显式表达并且可用来特别地针对一个或多个因素(例如,时间、成本……)优化工作流处理。例如,可以按照项目和任务依赖关系来分割任务以使得能够跨多个处理器和/或计算机并发执行。另外,关于工作流执行状态的有组织且有意义的消息可例如通过图形用户界面(GUI)传递给开发者。
[0028] 在初始工作流执行之后,能够在对互相依赖的持久存储的项目(例如,文档、文件、文字(例如,组件名称)……)的后续改变中维护这些项目之间的约束,以确保工作流保持一致状态。根据一种实施方式,项目是否已经改变可以如所需那样粗糙地或精细地定义,并且不一定是依赖时间的。一旦检测到改变,注意力就转向最小化传播该改变并返回至一致状态所需的工作量。能够再次采用工作流依赖关系来将重新执行限于该工作流中受该改变影响的子集。所公开的其他特征涉及撤消动作以及与常规工作流系统的可互操作性,等等。
[0029] 现在参考附图更详细地描述本发明的各个方面,在全部附图中用相同的标号来指示相同的或相应的元素。然而应该了解,附图及其相关详细描述不旨在将所要求保护的主题限于所公开的具体形式。相反,其意图是覆盖落在所要求保护的主题的精神和范围之内的所有修改、等效和替换的方案。
[0030] 首先参考图1,示出了工作流系统100。工作流系统100包括工作流引擎110,该工作流引擎110通常用于执行或处理工作流,其中工作流是定义过程或程序的互相关任务和项目集。任务描述要采取的动作(例如,复制、删除、调用……),并且进一步定义其本身之间的依赖关系、输入和输出。项目可以是任务输入和/或输出(例如,文件、文档、特性……)。例如,任务可消费一个或多个项目作为输入并任选地产生一个或多个项目作为输出。或者,任务可以在不接收一个或多个项目作为输入的情况下产生一个或多个项目作为输出。工作流引擎110获取工作流或其表示以及任何必需项目,执行工作流,并且可任选地产生结果(例如,一个或多个文档的集合、文件、可执行代码……)。
[0031] 工作流系统100能够在许多不同的上下文中采用,包括但不限于业务/企业过程和计算机软件开发。出于清楚和明白的目的,所公开的主题的各方面和各实施方式将参考业务/企业过程或计算机软件开发来描述。当然,所要求保护的主题不旨在由此受限。
[0032] 还应注意,术语可随上下文变化,而所述概念、特征和/或功能保持不变。例如,在具体参考软件开发上下文时,术语“构造”可以代替此处的单词“工作流”。由此,工作流系统100可被称为构建系统100,工作流引擎110可被称为构建引擎110,而工作流可被称为构建。类似地,任务、项目、输入和输出等可理解地随上下文变化,而不按照对所要求保护的主题的范围或适用的上下文提出限制的任何方式。
[0033] 根据一种实施方式,工作流可通过程序从用通用编程语言(例如,Visual ……)指定的工作流描述(也称为配置文件/脚本、描述文件、构建文件/脚本/配置)中构造,通用编程语言通常是独立于域的且图灵完整的。以此方式,工作流可利用通用编程语言的可表达性,包括特定语言特征或编码技术,诸如但不限于继承、参数化和条件等。换言之,通用语言允许容易地描述或定义各种各样的关系,包括任意复杂的关系。
同样,通过采用通用编程语言,工作流及其开发者可利用与特定语言相关联的常规工具,诸如调式器、类型校验器和代码优化器,等等。如图1所描绘的,开发者可指定通用程序120,该通用程序120描述工作流并且在被执行时构造工作流或其表示(例如,对象图)。
[0034] 当前,趋势是使用域专用语言(DSL)或可扩展标记语言(XML)来指定工作流。然而,例如由于其声明性特性,DSL和XML限制可用于描述工作流的可表达性或计算种类。换言之,DSL和XML当前不具有表达可由通用编程语言(例如, Visual……)表达的所有计算的能力。更正式地,通用编程语言被称为图灵完整的,这意味着它们能够表达图灵机可计算的任何事物。相反,XML不是图灵完整的,而虽然DSL可以是图灵完整的,但DSL常规上是以不是图灵完整的显式目标设计的。类似情形是正则表达式和无上下文语法之间的表达能力差异,其中正则表达式能够描述的比无上下文语法能够描述的少。这里对于DSL和XML对比通用编程语言亦是如此。例如,如果DSL不实现继承、功能参数化或条件,则无法用该DSL表达特定事物。因此,存在无法由DSL和XML描述的特定工作流。此外,对继承、参数化和条件的本机支持以及由特定通用编程语言提供的其他功能由于数十年的演变而被很好地设计,并且通常比可作出以模拟/模仿类似功能的对DSL或XML的任何扩展好得多地执行。
[0035] 作为示例,考虑贷款批准过程,包括需要由申请人审阅并签署并由贷款人评估的多个相关文档。在常规系统中,将需要为每一个特定贷款人生成工作流,因为每一个贷款人的文档和过程本身可能有差异。然而,更好的方法将会是产生可以为每一个特定贷款人参数化的通用贷款批准过程。换言之,可以指定可以用不同的参数(例如,贷款文档、条款和条件……)来实例化的工作流。此外,假设申请过程对于美国公民和非公民稍有不同。在这种情况下,可以在工作流中指定条件。此外,可使用继承来指定各种类型的申请者之间的不同。参数化、条件和继承全都由诸如 或Visual 等面向对象的通用编程语言来本机地支持。虽然可作出向DSL或XML添加类似功能的尝试,但结果将会是设计糟糕的小型语言。
[0036] 此外,DSL和XML不具有传统上与通用编程语言相关联的所有工具,包括类型校验器、调式器以及代码优化器等等。作为示例,如果使用强类型通用编程语言来构造工作流,则可对该工作流进行类型校验以减少编码差错。例如,源代码可具有类型“Source(源)”而汇编件可具有类型“Assembly(汇编件)”,并且如果试图将汇编件作为源文件来传递,则类型校验器可以例如在编译时指示这是错误的。另外,可以采用调式器来测试和调试工作流,并且使用代码优化器来优化工作流的规约。
[0037] 此外,利用通用编程语言来构造工作流使得能够对工作流进行元编程,其中元编程指的是相对于仅仅能够执行工作流,观察、推理、交互、操纵和/或生成工作流的能力。例如,假设表示人类飞行员在飞行时执行的工作的工作流。此外,假设实施飞行员不能工作超过十个小时,之后需要由新飞行员来代替的限制。可以编写分析工作流并确定该工作流是否能够在十小时内完成并决定是否需要两个飞行员的程序。类似地,可以分析工作流以确定其是否能被分割并且在多个处理器和/或机器上运行。另外地或另选地,可以分析工作流以确定是否能够通过交换任务或以不同次序执行任务来优化执行。
[0038] 此外,工作流可被输入到其他工作流中,或者换言之,工作流可以是可自适用的,以使得能够产生推理、改变、生成和/或更新其他工作流的工作流。作为示例,假设如果开发者产生代码,则要求该开发者对该代码进行数字签名。如果存在未签署代码的第一工作流,则可采用变换该第一工作流以使其确实签署代码的第二工作流。
[0039] 通用程序可构造互相关节点图。图2提供了节点实例和关系的图形表示以帮助对其进行进一步讨论。节点210可包括输入和输出的列表以及在不同的图构造之间一致且稳定的唯一标识符(ID)。唯一标识符可依赖于图中的上游节点(它依靠的事物)以便允许即使在工作流本身改变时也部分地执行工作流,如将在下文中进一步描述的。每一个节点210可以是项目220或者任务230。
[0040] 项目220可描述任务需要运行的信息。例如,项目可以是作为元数据传递给任务的文件或特性(例如,用于配置工作流的键/值对)。在得到支持的情况下,项目可以是强类型的,以减少编码差错几率。作为示例,编译程序的特性可以告诉编译程序是产生库还是产生可执行代码(exe):“Property”,其中“TargetType(目标类型)”被定义为“public enumTargetType{Library,Exe}”。由此,在编译构建图的程序时,编译程序可强制实施对该特性的有效输入。对于文件亦如此。例如,编译程序可采取“Assembly(汇编件)”类型,该类型从如“Reference(引用)”自变量的类型“File(文件)”导出,以便强制实施只为该特性传递汇编件(例如,可执行代码(exe)、动态链接库(d11)……)。虽然项目220可由一个或多个任务消费,但项目220还可由任务230在执行时产生。
[0041] 任务230描述要采取的动作以及对于该动作的双撤消动作。任务230可具有指示或参数化动作的输入项目集220。例如,编译任务可具有输入,诸如源文件列表、汇编件名称、汇编件引用和目标类型,等等。任务230还可具有由动作产生的输出项目。例如,编译程序可产生汇编件作为输出。
[0042] 由任务230描述的动作和和撤消动作可被表示为被示为动作250和撤消260的命令240。作为示例,对编译程序的外壳执行命令调用可基于诸如“csc.exe/r:system.dll/t:library foo.csc/out:foo.dll”等输入项目来被表示为具有一组自变量的命令动作250,其中“csc.exe”调用编译程序,“system.dll”和“foo.csc”表示输入,而“foo.dll”是输出。尽管可定制,但任务的默认撤消命令260是标识并移除输出文件。因此,在以上示例中,撤消命令260将删除“foo.dll”。在一种实施方式中,任务230还负责注册其自身、输入和输出之间的依赖关系。
[0043] 命令240包括用于执行动作的所有信息。一旦构造,命令240就可以是自包含的(但它能够知道创建它的任务的唯一ID)且可串行化的,以使得命令240能够被传送至不同的机器并由该不同的机器执行。换言之,命令可被表示为数据,从第一计算机串行化、发送到第二计算机,由第二计算机来去串行化并执行。此外,命令可以是自包含的且可串行化的,以允许撤消命令被存储在文件中并且用于撤消与不再作为工作流的一部分存在的任务相关联的动作。命令240还可具有指示命令240的成功或失败的执行方法以及自动将每一个记录的消息与拥有该命令的任务相关联的特定记录器,如将在下文中进一步描述的。命令的一个示例是“ShellExecuteCommand(外壳执行命令)”,该命令取得用于运行或执行的可执行代码、一组自变量和退出代码(例如,成功执行、失败)并且在执行时将使用操作系统应用程序编程接口(API)来执行外部命令,以便向记录器提供消息,并基于该命令的退出代码来返回成功或失败。
[0044] 最终,节点集210可被称为目标270。这一目标270可被传递至工作流引擎并用于发现并执行要完成的工作。
[0045] 以下是可利用诸如 等通用编程语言来生成并在执行时构造工作流的示例性通用程序:
[0046]
[0047] 此处,指定两个汇编件,其中第二个引用第一个。此外,第二个汇编件在资源(例如,字符串、图像、持久存储对象……)中链接,该资源通过将“resx”文件格式转换成资源文件的资源文件生成器工具来馈送。此外,“Csc”、“ResGen”和“CopyFiles(复制文件)”是从“Task(任务)”导出的类,而“Task.SourceFile(任务.源文件)”、“ResxFile”、“Assembly”和“ResourceFile(资源文件)”是从“Item(项目)”导出的类。更具体而言,在该示例性面向对象语言实现中,必需的输入可被传递至任务的构造器,而任选项目可通过设置特性或方法调用来注册。
[0048] 执行以上代码将在存储器中创建类似于图3所示的图。此处,源文件项“FIRST.CS”310作为输入被提供给编译程序任务“CSC”312以产生第一汇编件314。源文件项“SECOND.CS”320被提供给编译程序任务“CSC”322。此外,项目“SECOND.RESX”330被提供给生成器任务“RESGEN”332以产生资源项“RESXFILE”334,该资源项作为输入被提供给编译程序任务“CSC”322。同样作为输入被提供给编译程序任务“CSC”322的是项目“FIRSTASSEMBLY(第一汇编件)”314。编译程序任务“CSC”322输出汇编项“SECONDASSEMBLY(第二汇编件)”324。项目“FIRSTASSEMBLY”314、“SECONDASSEMBLY”324和“RESULT(结果)”342作为输入被提供给任务“COPYFILES(复制文件)”340,该任务输出形成“TARGET(目标)”350的项目“LAYOUT(布局)”344。
[0049] 返回到图1,工作流引擎110包括获取组件112,该获取组件可接收、检索或以其他方式获取通过程序执行构造的工作流。例如,获取组件112可包括应用程序编程接口(API),该API可用于传递工作流的图或者图的位置,例如存储器中或某一持久存储上。另外,获取组件112可对工作流执行某一预处理操作以确保该工作流处于适当的形式以便处理。例如,如果循环是不理想的,则获取组件112可执行已知或新颖的算法以检测和报告循环的存在。此外,可以对工作流中的项目执行确认操作。例如,如果文档被假定为其中具有签名,则可检查该文档以确保该签名实际上存在而不是空白图像或其他无效输入。
[0050] 一旦由获取组件112获取并且可任选地确认,调度组件113就可调度所获取的工作流的执行或处理并且更具体而言调度工作流中的每一个任务以便执行。此外,调度组件113可考虑各种因素,管控何时、何地以及如何调度任务以便执行以针对一个或多个因素优化工作流执行,如将在下文中进一步描述的。例如,由工作流捕捉的项目和任务依赖关系可用作将任务分割成独立子集以便例如跨多个处理器和/或机器并发执行的基础。在执行后,工作流状态130可被保存到诸如文件等持久存储以供稍后引用。随后,可采用工作流状态130来帮助确定是否已经对工作流作出改变并且帮助工作流的至少一个子集的有针对性的重新执行。
[0051] 注意力转向图4,更详细地描绘了代表性调度组件113。虽然可以在一个步骤中简单地调度任务执行,但根据一种实施方式,调度可被分成两个阶段,即分别由任务组件410和命令组件420标识的任务调度和命令调度。特别地,这提供了动作描述和动作执行之间的分隔,这可帮助并行和/或分布式处理以及撤消动作。如上所述,任务可描述需要采取的动作以及双撤消动作。相反,命令包括执行动作或撤消动作所需的所有信息。作为示例,可首先创建将动作或撤消表示为数据的数据结构,并且接着由此执行表示动作的数据结构,以便有效地执行所述动作以使得“F(a)=execute(new F(a))”。因此,任务能够本地地执行或被传递至另一计算机用于执行。类似地,撤消动作能够与工作流状态存储在一起以使得即使对应的任务不再形成工作流的一部分也可执行该撤消动作。因此,动作412或撤消动作414可由任务调度组件410来调度执行,并且随后命令调度组件420可调度实现所述动作422或撤消动作424的命令的执行。
[0052] 在操作中,与命令调度组件420相比时,任务调度组件410可实现高级调度操作。例如,任务调度组件410能够首先定位不具有工作流所产生的输入的任务,并通过将这些任务传递给命令组件420来调度那些动作执行。当任务完成时,任务调度组件410可检查已完成的任务的输出中的任意个是否由其他任务消费。对于这些任务中的每一个,可检查是否所有输入可用,并且如果是,则通过将动作的描述传递给命令调度组件420来调度该任务执行。此外,如果在进行状态检查时相关联的任务动作不再是工作流的一部分,则任务调度组件410可调度撤消动作。更具体而言,任务调度组件410可从持久存储状态去串行化对应于该任务的撤消命令,并将该命令传递给命令调度组件420或以其他方式使该命令对命令调度组件420可用。
[0053] 一旦调度任务执行,命令调度组件420就能够在本地机器上(例如,跨一个或多个处理器或核)、多个机器上、云中或任何其他执行上下文中调度命令执行。默认地,命令调度组件420能够以完全利用特定执行上下文的资源的方式调度命令以最小化处理时间。对于调度执行的每一个任务,可作出各种进一步检查以确保例如所有输入可用并且能够执行任务。在这些检查中,可以确定任务是否已经改变并且服从执行,如将在本文稍后描述的。一旦确认将执行任务,就可从该任务获取动作和撤消动作命令422和424。撤消动作命令424然后可被持久存储到状态存储,并且动作命令422被调度在例如线程上执行。此外,如果撤消动作或命令可从先前运行中获取,则撤消命令动作424也可被调度执行以反转先前执行的相关动作424的效果。
[0054] 状态更新组件430被配置成确保任务输入和输出状态被保存到持久存储(例如,文件、数据库、云……)以供工作流引擎110的后续运行使用。如果诸如状态文件等存储不存在,则状态更新组件430可创建这一存储。在任务或命令执行完成时,可存储关于任务的输入和输出的状态信息。在一种情况下,该信息可以是标识改变输入和产生输出的最后一次时间的时间戳。然而,所要求保护的主题不限于此,如将在本文稍后章节中描述的。在任何情况下,存储允许确定状态是否跨工作流的运行改变的信息。此外,状态更新组件430可将与已执行的任务相关联的撤消命令持久存储到存储以允许随后即使任务不再是工作流的一部分也撤消动作。
[0055] 上下文组件440提供上下文信息以帮助调度。换言之,基于由上下文组件440提供的上下文或信息,工作流执行能够以最优方式调度。在一种情况下,上下文组件440可获取并提供关于执行上下文的信息,诸如机器和/或处理器或其他可用资源的数量。上下文组件440还可例如通过对工作流进行元编程来获取并提供关于工作流本身的信息,诸如大小、深度和宽度以及依赖关系等。在一种情况下,这一信息可用于根据执行优先级来分配和执行任务。在另一示例中,可分析工作流依赖关系以确定通过打破某些依赖关系并多次执行动作来提高性能是否是可能的。此外,可以理解,可以动态地提供上下文信息以使得调度能够响应于动态上下文信息来基本上实时调整。例如,调度可基于与一个或多个处理器和/或机器相关联的负载信息来更改。
[0056] 调度组件113是可插入的,以使得调度可由通过插件组件450注入的特定逻辑管控。由此,调度组件113的功能不是固定的,而是可扩展的。作为示例,可扩展调度以便针对诸如能耗等除了时间之外的某一事物进行优化。利用插件组件450,调度组件113可被更改成在能量较便宜时,例如在晚上调度任务执行。上下文组件440还可由插件组件450更改,以获取并接收能耗信息以使得调度能够例如动态地调整。另外地或另选地,调度可被修改成远离使用具有较大固定驱动器的机器以最小化能量使用。
[0057] 简要地返回到图1,工作流引擎110还包括记录组件114,该记录组件被配置成以提供给例如开发者的消息或通知的形式观察和展示执行信息。此外,数据类型可以与消息相关联以提供关于消息的附加信息以及用于消息分类的手段。作为示例而非限制,记录组件114可展示具有各种子类型的三种类型的消息,即通用工作流消息(例如,开始、成功、失败……)、任务状态消息(例如,任务排队、任务开始、任务改变状态、任务失败、任务成功……)和/或命令执行消息(例如,信息、警告、错误……)。此外,这些消息类型可携带不同种类的细节。例如,通用工作流消息可包括工作流图,任务消息可包括它们适用的任务,而命令执行通知可包括它所属的任务以及任选源位置。
[0058] 特别地,消息类型校验允许以易于理解的结构化方式展示复杂的记录。作为示例,在其中在单处理器计算机上执行工作流的简单上下文中,记录组件114可以在事物串行地执行时产生这些事物,诸如“任务A”、“任务B”和“任务C”。然而,当并行化或分布任务的至少一个子集时,相同的记录组件114将使来自任务的消息交错。通过将特定类型链接到消息,能够通过记录组件114来容易地过滤消息。例如,记录组件114可提供与特定任务或可被标识最多警告的任务相关联的消息。这一结构化信息对于工作流调试尤其有帮助。
[0059] 参考图5,描绘了代表性记录组件114。如图所示,记录组件114可包括各种特定记录器,或可另选地记录组件114能够以不同的形式具体化。例如,记录组件114包括通过命令行接口展示通知的控制台记录组件510。另外地或另选地,可以采用将通知保存到文件或其他持久存储的数据结构的文件记录组件520。记录组件114也是可插入的。换言之,可添加诸如插件组件530等附加组件以扩展、修改或替换现有或默认记录功能。在一个示例中,插件组件530可提供丰富的图形用户界面,以便以易于理解的方式显示工作流消息,而不是简单的消息列表。
[0060] 图6示出了可用于工作流引擎110且更具体而言用于记录组件114的示例性图形用户界面(GUI)600的屏幕截图。GUI 600包括多个图形元素以帮助呈现信息,包括多个窗口或窗格以及文本等。窗口610提供尚未被处理的所有任务的列表,例如因为这些任务具有阻塞这些任务的依赖关系或者不存在可供执行该任务的资源。窗口620列出其命令当前正在例如一个引擎线程上运行的任务。窗口630标识已经完成的任务。此外,可以过滤这些已完成的任务以显示错误、警告、成功和/或改变状态。在640处显示关于选自窗口610、620或630的任务的文本细节。窗口650示出与所选任务相关联的消息,该消息的细节可以在660处提供。另外,如果存在源位置,则点击该位置将启动编辑器以检查源位置。最终,进度条670可视地描绘工作流过程的进度。尽管此处未示出,但在一种实施方式中,可采用不同的颜色来提供附加信息。例如,亮绿色指示没有改变,暗绿色意味着成功,蓝色对应于正在进行中,灰色表示排队的任务,红色对应于错误,而橙色指示警告。
[0061] 回头参考图1,在最初执行或处理工作流之后,可能需要重新运行该工作流。例如,如果对一个或多个项目作出改变,则这些改变可传播通过工作流以维护有效或一致状态。在代码构建上下文中,如果例如实质上重制源文件(例如,添加和/或删除方法),则可以重新执行工作流以使得在诸如汇编件等任何输出结果中反映这些改变。改变检测组件115被配置成标识改变。
[0062] 常规工作流系统依靠时间戳来确定项目(例如,文件、文档……)是否是最新的。更具体而言,将输入项目时间戳与同工作流输出相关联的时间戳进行比较,并且如果它们是相同的,则该项目被认为是最新的;否则该项目已经改变。该方法存在若干问题。首先,如果工作流不产生输出,则项目被认为已经改变。第二,诸如病毒扫描程序等其他程序可接触文件并更改时间戳,这导致这些项目被认为过期。此外,在分布式计算上下文中,机器时钟可以是稍微不同的,这导致项目被误认为已经改变或未改变。
[0063] 虽然改变检测组件115可利用常规时间戳机制来确定改变,但根据一种实施方式,对项目是否已经改变的定义可以如所需那样地精细粒度或粗糙。例如,比常规时间戳更精细粒度的方法将会是比较由任务消费和产生的项目的时间戳。此外,确定某一事物是否已经改变不一定完全基于时间戳,而事实上可以是不依赖时间的。
[0064] 转向图7,更详细地描绘了代表性改变检测组件115。如图所示,改变检测组件115包括定义组件710和评估组件720。定义组件710可定义改变对特定项目意味着什么。评估组件720针对特定定义以及可能的某一持久存储的状态信息来评估项目。此外,可针对特定任务为项目定义改变定义。此外,改变检测组件115是可插入的。换言之,如由定义组件710和评估组件720定义和实现的改变意味着什么的概念可由插件组件730提供的逻辑来修改、更新或替换。
[0065] 作为改变检测的示例,考虑其中文件标题改变的情形。常规上,由于与文件相关联的时间戳已经改变,因此该项目将被认为已经改变。然而,这种情况下对文件改变的定义可能排除对标题的改变。因此,当由评估组件720评估时,该文件将不会被认为已经改变并由此工作流将不会重新运行。
[0066] 在另一示例中,根据改变定义,评估组件720可将文件的当前版本与先前存储的版本或其一部分进行比较以确定该文件是否已经改变。类似地,可以在初始工作流执行时对文件应用诸如散列函数等函数,该函数的值可被存储为状态信息。随后,定义组件710可指示散列函数将被应用于文件的当前版本并且所得一个或多个值将与被存储为状态的那些值进行比较。
[0067] 参考图1,在改变检测组件115检测到改变时,可通过通知调度组件113一个或多个特定项目已经改变并且工作流需要重新运行来传播改变。然而,不像常规系统,工作流引擎110无需在任何改变后重新运行整个工作流。相反,可分析任务和项目之间的依赖关系并且将重新执行限于工作流中的受到一个或多个改变影响的子集。例如,如果任务“A”依赖于任务“B”而任务“C”依赖于任务“D”和“E”,则对任务“B”的改变将导致任务“A”的重新执行而不是任务“C”、“D”和“E”,因为任务“A”和“B”和任务“C”、“D”和“E”是独立子集。换言之,只要发生改变,只执行将工作流带回到一致状态中所需的最少量的工作。
[0068] 此外,在工作流处理期间,工作流引擎110还可例如经由调度组件113,通过对中间项采用匿名位置来避免隐藏依赖关系。作为示例,假设任务“A”之后是任务“B”,并且在执行时,任务“A”在特定位置放置文件。任务“B”被编码成从该特定位置检索文件并执行某一动作。此处,该特定位置是隐藏依赖关系,其中将文件放置在该特定位置是惯例,但该特定位置未在工作流中显式编码。这是有问题的,至少因为工作流引擎110不知道并且无法推理该依赖关系。相反,对该依赖关系的认知被限于工作流开发者。结果,工作流引擎110无法确定任务是否能够是分布式的或者并行运行以及一个任务是否能够在另一个任务之前运行。为了解决隐藏依赖关系,工作流引擎110可将中间文件等存储到匿名位置,这些匿名位置是在工作流执行之前未知的位置。以此方式,开发者无法知道中间文件将被存储在哪里并创建隐藏依赖关系。因此,通过利用匿名位置,开发者被迫在工作流中显式表达依赖关系。换言之,工作流引擎110可以不考虑未在工作流中表达的依赖关系。
[0069] 参考依赖关系,能够在工作流中显式表达任务和项目依赖关系两者。常规系统不提供真实的依赖关系跟踪。更具体而言,通常只表达任务依赖关系,而完全不顾项目依赖关系。结果,工作流系统性能受到损失,因为并发执行机会就算有也是有限的。例如,即使工作流引擎知道任务将以特定顺序次序执行,也无法利用并发任务执行,因为任务可依靠相同的项目或产生由另一任务使用的项目。该问题在依赖关系在工作流中隐藏而不是表达的情况下进一步复杂化。然而,通过在工作流中显式地捕捉所有任务和项目依赖关系,工作流可被分成该工作流的独立子集,这些独立子集可用于支持至少并发执行并且选择工作流的重新执行。
[0070] 作为捕捉到的项目和任务依赖关系以及如上所述的调度执行工作流的一部分的能力的结果,注意,可以选择一个或多个节点来重新执行。例如,图的可视化可经由可从中选择节点的图形用户界面提供给开发者。这在与较大组产品一起工作时可以是有利的。考虑包括文字处理程序、电子表格和演示组件的office软件套装。如果开发者只关心文字处理程序组件,则他们可指定在作出改变后被重新执行的构建的一部分。换言之,较大的图可被拆分成子图并例如使用元编程来提供以便执行。
[0071] 工作流引擎110还包括导入组件116和导出组件117以便于与现有常规工作流系统进行交互。工作流引擎110可操作由通用程序创建的依赖关系图。常规域专用语言和XML工作流可由导入组件116转换或封装以允许可互操作性。在一个实现中,导入组件116可包括解析器和重写器,该解析器和重写器解析现有工作流并将该工作流重写为在被执行时创建依赖关系图的通用程序。或者,在所公开的系统中,现有工作流可被封装为任务。与导入相对的是将依赖关系图和/或从通用语言描述中产生的其他工作流表示导出到域专用语言、XML或其他表示。导出组件117可执行该功能以便通过以任何目标表示重写所公开的工作流来转换该工作流。
[0072] 工作流系统可以比处理工作流做得更多。如图8的工作流系统800所示,工作流引擎110还可包括对于例如程序创建工作流的测试组件810和设置组件820。测试组件810被配置成对工作流代码和/或由工作流产生的结果执行一个或多个测试。此外,测试组件810可利用工作流依赖关系来对工作流代码的仅仅一部分和/或在可能的情况下由此产生的结果执行。常规上,开发者构建所有代码并且然后运行可以是复杂过程的众多测试。此外,构建(例如,被执行以构建或产生程序的各种任务(例如,调用编译程序、链接代码、将文件复制到目录……))可花费至多一小时并且测试可花费多日来完成。如果作出改变,则常规上重新构建代码(例如,不同版本)并且从开始启动测试执行。然而,测试组件810可使用关于改变和依赖关系的信息并执行所有测试的子集,其中该子集只针对该改变和由此被影响的代码(例如,500次测试而非100,000次测试)。因此,测试组件810可降低对软件产品作出修改的成本。
[0073] 设置组件820被配置成生成构建设置以便于软件安装。常规上,构建系统通常被设计成将源代码取作输入并产生二进制代码作为输出。然而,通常期望创建可用于在计算机上安装已构建的软件的可执行代码。当前,开发者单独生成设置工作流。在一种情况下,设置组件820可利用元编程,通过分析构建的(诸)输入和(诸)输出来自动生成设置工作流。此外,在构建改变的情况下,设置组件820可利用工作流或更具体而言是利用构建依赖关系来创建由改变影响的设置部分。类似于测试组件810,设置组件820同样降低修改软件的成本。
[0074] 已经关于一些组件之间的交互描述了上述系统、体系结构等。应该理解,这样的系统和组件可以包括这些组件或其中指定的子组件,某些指定的组件或子组件,和/或附加的组件。子组件也可以被实现为在通信上被耦合到其他组件而不是被包括在父组件中的组件。此外,一个或多个组件和/或子组件可以结合成提供聚集功能的单个组件。系统、组件、和/或子组件之间的通信可以根据推(push)和/或拉模型来实现。各组件也可以与一个或多个其他组件进行交互,出于简要考虑在此未具体描述该组件但本领域的技术人员均已知。
[0075] 此外,应该明白以公开的系统以及以下方法的不同部分可以包括或包含基于人工智能、机器学习或知识或规则的组件、子组件、进程、装置、方法或机制(例如,支持向量机、神经网络、专家系统、贝叶斯信任网络、模糊逻辑、数据融合引擎、分类器等)。这样的组件和其它组件可以自动化执行某些机制或进程,由此使得系统和方法的各部分更为自适应、高效及智能。
[0076] 作为示例而非限制,改变检测组件115和调度组件113可采用这些机制。例如,可采用元编程来推理工作流并推断项目何时改变,而不是请求定义对项目的改变。类似地,调度组件113可采用上下文信息来推断何时调度任务和/或命令执行以便针对时间或其他因素来进行优化。
[0077] 考虑到以上描述的示例性系统,参考图9-15的流程图将可以更好地理解根据所公开的主题实现的方法。尽管为了简洁起见,作为一系列框示出和描述了方法,但是,应该理解,所要求保护的主题不仅限于所描述的框的顺序,一些框可以按与此处所描绘和描述的不同的顺序进行和/或与其他框并发地进行。此外,并非所有的所示出的方框都是实现下面所描述的方法所必需的。
[0078] 参考图9,描绘了根据一种实施方式的通过程序创建工作流的方法900。在附图标记910,接收用通用编程语言(例如, Visual ……)描述工作流的程序。在标记920,检查接收到的程序以查找编码错误。作为示例,在该程序是强类型的情况下,可以例如在程序编译期间执行类型校验。此外,可对工作流应用与通用编程语言相关联的其他工具,包括调式器和/或代码优化器等。在附图标记930,执行程序以生成工作流。例如,工作流可被表示为表示工作流项目和任务的互相关节点的依赖关系图,其中项目和任务依赖关系两者都在工作流中显式表达。总而言之,工作流可通过程序创建,而不是直接声明。类似地,该技术类似于汽车和制造汽车的工厂之间的差异。此外,能够更快地创建工作流,并且例如利用域专用语言或标记语言,比直接声明的工作流更容易地产生复杂工作流。
[0079] 图10示出了初始工作流处理方法1000。在附图标记1010,获取通过程序构造的工作流。例如,可以在执行描述包括多个项目和任务的工作流的通用程序之后从存储器中获取该工作流的图。在标记1020,从开始到完成地执行工作流。例如,作为包括以特定次序编译源文件在内的一系列构建任务的结果,描述代码构建的工作流可产生二进制文件。此外,工作流可按照工作流中表达的项目和任务依赖关系来分成独立子集,并且可启动两个或更多独立子集的并发执行。在标记1030,记录(例如,经由控制台、文件、用户界面……)关于工作流的执行的一个或多个类型化消息。消息类型可包括但不限于通用执行状态(例如,开始、成功、失败……)、任务状态(排队、开始、失败、成功……)以及命令执行信息(例如,警告、错误……),其中每一种消息类型可携带各种详细信息,诸如工作流图、任务标识和源位置。特别地,由消息类型提供附加信息使得能够以有组织的方式展示消息,例如以便帮助理解或者换言之高效地向用户传达信息。
[0080] 图11描绘了在改变后重新执行工作流的方法1100。在附图标记1110,检测对诸如项目等工作流的一部分或工作流本身的改变。在标记1120,分析工作流依赖关系以标识受检测到的改变影响的项目和/或任务。在标记1130,基于改变和依赖关系来重新执行工作流的至少一个子集。换言之,除非改变影响整个工作流,否则调度工作流的所选部分来重新执行。在标记1140,例如在移除先前是工作流的一部分的任务的情况下,可撤消一个或多个动作的结果。尽管不限于此,但在一种情况下,撤消动作可通过删除先前任务动作的结果来反转该动作。在标记1140,可将关于工作流重新执行的类型化消息记录到控制台、文件或用户界面以展示内部动作和/或状态。此外,能够利用与消息类型相关联的信息来以易于理解的方式组织消息。
[0081] 图12是根据一种实施方式的检测改变1200的方法的流程图。在附图标记1210,获取改变定义,其中改变定义定义改变对于特定工作流项目(例如,文件、文档、汇编件……)意味着什么。根据一种实施方式,开发者可指定改变定义。或者,对于特定项目类型可存在默认定义,或者可从其他定义或改变的安全概念等推断该定义。在标记1220,例如从状态文件中获取关于项目的先前状态的信息。在标记1230,将改变定义应用于项目的先前状态和当前状态以确定该项目是已经改变还是尚未改变。例如,如果改变定义需要严格标识,则比较先前状态和当前状态,并且如果存在任何差异,则该项目将被认为已经改变。在标记1240,输出对项目是否改变的判定。任务是否已经改变可基于任务的至少一个输入或输出项目是否已近改变来确定,如上所述。
[0082] 图13是对已改变的工作流执行动作的方法1300的流程图。在附图标记1310,标识已改变的工作流的工作流任务和项目之间的依赖关系。在1320,按照改变以及由该改变影响的项目和任务来标识工作流的子集。在附图标记1330,对所标识的工作流子集执行动作。这些动作可包括与工作流处理相关联的那些动作以及其他动作。作为示例而非限制,这些动作可对应于在其中工作流对应于构建过程的代码上下文中测试或生成设置或安装过程。以此方式,运行测试和构建设置的成本能够在工作流中发生改变时降低,因为只可执行受改变影响的那些动作。
[0083] 图14描绘了根据一种实施方式的包括任务调度的工作流执行的方法1400。在附图标记1402,例如从状态文件中加载与工作流相关联的任何可用状态信息。这一信息可描述先前处理的工作流的组件项目的状态等。在标记1404,启动工作流记录器并且向工作流引擎注册自定义记录器以使得能够展示工作流处理信息,包括对排队的、正在运行的和/或已完成的任务的标识以及与这些任务相关联的任何错误或警告。在标记1406,例如从通过程序构造的工作流依赖关系图中标识工作流节点。在一个实现中,与目标节点相关联的信息可结合常规图算法来利用以标识图中的项目和任务节点。工作流引擎可能需要避免循环工作流图。在这种情况下,在1408,可利用已知或新颖的图算法来执行循环检测并报告所标识的循环,包括例如对循环的完整描述。
[0084] 在附图标记1410,获取每一个节点的唯一且稳定的标识符(ID)。在标记1412,通过引用所加载的状态信息来确定先前可用的任何节点ID是否不可用。这一情形可以在稍后移除先前形成工作流的一部分的任务时发生。在1412,如果确定对于唯一节点标识符对于工作流的先前状态存在并且不再形成工作流的一部分(“是”),则在1414调度相关联的撤消动作。否则,该方法在1416处继续。在一种情况下,能够去串行化存储在状态文件中的撤消命令并调度该命令执行。这使得即使任务不再形成工作流的一部分,也能够撤消或反转该任务的结果。
[0085] 在标记1416,调度任务执行。这可包括利用标准图算法来标识不具有通过后续任务执行产生的输入的任务,并首先调度这些任务执行。当任务完成时,可检查其输出中的任意个是否由其他任务消费,并且对于这些任务中的每一个,如果所有输入可用,则调度这些任务执行。在附图标记1418,检查是否已经处理所有节点。如果尚未处理所有节点(“否”),则该方法在1416处继续以调度任务执行。如果已经运行工作流中的所有节点(“是”),在1420保存所有项目的状态并且该方法终止。
[0086] 图15是根据一种实施方式的任务执行方法1500的流程图。在如图14的方法1400中所提供的调度任务执行之后,可执行以下动作。在附图标记1502,确定是否已经产生对已调度任务的输入。如果一个或多个输入不可用(“否”)(例如,任务被假定产生输入但失败),则在1504指示任务执行失败并且该方法终止。否则,如果所有输入可用(“是”),则该方法在1505处继续。此处,作出关于任务的所有输入和输出是否是最新的,或者换言之这些任务自从先前的任务执行(如果该任务先前被执行的话)以来是否尚未改变的另一次检查。如果所有输入和输出被确定为是最新的(“是”),则任务是最新的并且该方法终止。如果任务不是最新的,或者换言之任务已经改变(“否”),则该方法继续至1508,在那里确定是否已经调度撤消命令。在一种情况下,这可通过检查撤消命令的状态文件来查明。如果存在撤消命令(“是”),则该方法在1510处继续,在那里调度撤消命令例如在工作流引擎的一个工作者线程上执行。如果不存在撤消命令(“否”),则该方法跳过动作1510并继续至附图标记1512,在那里从任务获取动作和撤消命令。接着在1514,将对任务的撤消命令保存到状态文件。然后在标记1516调度该动作命令执行。最终,在完成动作命令执行时,在1518将关于任务的输入和输出的新状态保存到状态文件。
[0087] 在此所用的术语“组件”、“系统”和“引擎”及其各种形式意指与计算机相关的实体,其可以是硬件、硬件和软件的组合、软件、或执行中的软件。例如,组件可以是但不限于是,在处理器上运行的进程、处理器、对象、实例、可执行程序、执行的线程、程序和/或计算机。作为说明,在计算机上运行的应用程序和计算机都可以是组件。一个或多个组件可以驻留在进程和/或执行的线程中,并且组件可以位于一个计算机内和/或分布在两个或更多计算机之间。
[0088] 在本文中使用的词语“示例性”或其各种形式意味着用作示例、实例或说明。在此被描述为“示例性”的任何方面或设计并不一定要被解释为相比其他方面或设计更优选或有利。此外,各示例只是出于清楚和理解的目的来提供的并且并不意味着以任何方式限制或约束所要求保护的主题或本发明的相关部分。可以理解,本可呈现不同范围的多个其它或替换示例,但已出于简明的目的而省略了。
[0089] 术语“云”旨在意指诸如因特网等通信网络以及底层网络基础结构。云计算一般涉及基于因特网或云的应用程序或服务,包括但不限于软件即服务(SaaS)、效用计算、web服务、平台即服务(PaaS)和服务商业。尽管不限于此,但通常云服务经由web浏览器和网络连接对客户机可用,而服务被主存在一个或多个因特网可访问服务器上。
[0090] “持久存储的数据”等旨在意指存储在非易失性介质上的跨应用程序会话存在的数据。换言之,持久存储的数据经受应用程序启动和终止。相反,通常被保存在诸如存储器等易失性介质上的“瞬时数据”在应用程序会话中或期间创建并且在会话结束时丢弃。类似地,术语“持久存储”或其各种形式(例如,持久存储、正在持久存储、已经持久存储……)旨在意指以持久存储形式存储数据或将数据存储为持久存储数据。
[0091] “工作流”是定义过程或程序的操作方面的互相关任务集并且可消费和/或产生一个或多个项目(例如,文件、文档、可执行代码、文字……)。如此处所描述的,工作流能够由程序来描述和生成以及通过程序观察、推理和/或修改。此外,构建系统可以是工作流的一个实例,其中执行任务以生成或构建程序。然而,如此处所使用的,术语“工作流”并非旨在意指程序本身,其中对各数据片段执行动作。
[0092] “并发执行”等指的是同时而不是顺序地处理任务、工作流、命令或计算机指令的至少一部分。并发执行的一种形式包括并行处理,其中处理跨单个计算机上的两个或更多处理器或核进行。并发执行的另一种形式包括分布式处理,其中处理跨两个或更多计算机进行。此外,并发执行可涵盖并行处理和分布式处理两者,以使得处理跨多个计算机和处理器或核进行。
[0093] 如此处所使用,术语“推论”或“推断”通常指的是从经由事件和/或数据捕捉的一组观察结果来推理或推断系统、环境、和/或用户状态的过程。可以使用推断来识别特定上下文或操作,也可以生成,例如状态上的概率分布。推断可以是概率性的,即,基于对数据和事件的考虑,计算在感兴趣状态上的概率分布。推断也可以是指用于从一组事件和/或数据构成较高级别的事件的技术。这样的推断导致从一组观察到的事件和/或存储的事件数据构建新的事件或操作,不管事件在时间上是否紧密相关,以及事件和数据是来自一个还是多个事件和数据源。可采用各种分类方案和/或系统(例如,支持向量机、神经网络、专家系统、贝叶斯信任网络、模糊逻辑、数据融合引擎……)来执行关于所要求保护的主题的自动化和/或推断的动作。
[0094] 而且,对于在详细描述或权利要求书中使用术语“包括”、“包含”、“具有”、“含有”或其它形式的变型而言,这样的术语旨在包含在类似于术语“包括”的一种方式中,如同“包括”在用作权利要求书中的过渡词时所解释的那样。
[0095] 为了为所要求保护的主题提供上下文,图16以及以下讨论旨在提供对其中可以实现本主题的各方面的合适的环境的简要、概括描述。然而,合适的环境只是示例并且并非旨在对使用范围或功能提出任何限制。
[0096] 尽管能够在可以在一台或多台计算机上运行的程序的计算机可执行指令的一般上下文中描述以上公开的系统和方法,但是,本领域的技术人员将认识到,各方面也可以与其他程序模块等相结合地实现。一般而言,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、组件和数据结构等。此外,本领域的技术人员可以理解,上述系统和方法可用各种计算机系统配置实现,包括单处理器、多处理器或多核处理器计算机系统、小型计算设备、大型计算机、以及个人计算机、手持式计算设备(例如,个人数字助理(PDA)、电话、手表……)、基于微处理器或可编程消费者或工业电子设备等。各方面也可以在其中任务由通过通信网络链接的远程处理设备执行的分布式计算环境中实现。然而,所要求保护的主题的某些方面,如果不是所有方面的话,可以在独立计算机上实施。在分布式计算环境中,程序模块可以位于本地和远程存储器存储设备中的一个或两者中。
[0097] 参考图16,示出了示例计算机或计算设备1610(例如,台式机、膝上型计算机、服务器、手持式设备、可编程消费或工业电子产品、机顶盒、游戏系统……)。计算机1610包括一个或多个处理单元或处理器1620、系统存储器1630、系统总线1640、大容量存储1650以及一个或多个接口组件1660。系统总线1640通信地耦合至少上述系统组件。然而,可以理解,在其最简单的形式中,计算机1610可包括耦合到存储器1630的一个或多个处理器1620,该一个或多个处理器1620执行各种计算机可执行动作、指令和或组件。
[0098] 处理单元1620可以用通用处理器、数字信号处理器(DSP)、专用集成电路(ASIC)、现场可编程门阵列信号(FPGA)或其它可编程逻辑器件、分立门或晶体管逻辑、分立硬件组件或其任意组合来实现。通用处理器可以是微处理器,但在替换方案中,处理器可以是任何处理器、控制器、微控制器、或状态机。处理单元1620还可被实现为计算设备的组合,例如DSP和微处理器的组合、多个微处理器、多核处理器、结合一个DSP核的一个或多个微处理器、或任何其它这种配置。
[0099] 计算机1610可包括各种计算机可读介质或以其他方式与其交互以便于控制计算机1610来实现所要求保护的主题的一个或多个方面。计算机可读介质可以是能由计算机1610访问的任何可用介质,并包含易失性和非易失性介质以及可移动、不可移动介质。作为示例而非限制,计算机可读介质可以包括计算机存储介质和通信介质。
[0100] 计算机存储介质包括以用于存储诸如计算机可读指令、数据结构、程序模块或其他数据这样的信息的任意方法或技术来实现的易失性和非易失性、可移动和不可移动介质。计算机存储介质包括,但不限于,存储器设备(例如,随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)……)、磁存储设备(例如,硬盘、软盘、磁带盒、磁带……)、光盘(例如,紧致盘(CD)、数字多功能盘(DVD)……)、以及固态设备(例如,固态驱动器(SSD)、闪存驱动器(例如,卡、棒、键驱动器……)……)、或者可用于存储所需信息并且可由计算机1610访问的任何其他介质。
[0101] 通信介质通常以诸如载波或其他传输机制等已调制数据信号来体现计算机可读指令、数据结构、程序模块或其他数据,并包括任何信息传送介质。术语“已调制数据信号”指的是其一个或多个特征以在信号中编码信息的方式被设定或更改的信号。作为示例而非限制,通信介质包括有线介质,如有线网络或直接线连接,以及诸如声学、射频(RF)、红外线及其他无线介质之类的无线介质。上述的任意组合也应包含在计算机可读介质的范围内。
[0102] 系统存储器1630和大容量存储1650都是计算机可读存储介质的示例。取决于计算设备的确切配置和类型,系统存储器1630可以是易失性的(例如RAM)、非易失性的(例如ROM、闪存……)或是两者的某种组合。作为示例,基本输入/输出系统(BIOS),包括诸如在启动期间在计算机1610内的元件之间传输信息的基本例程,可被存储在非易失性存储器中,而易失性存储器可担当外部高速缓存存储器以便于处理单元1620的处理等。
[0103] 大容量存储1650包括相对于系统存储器1630用于存储大量数据的可移动/不可移动、易失性/非易失性计算机存储介质。例如,大容量存储1650包括但不限于,诸如磁盘或光盘驱动器、软盘驱动器、固态驱动器、或记忆棒之类的一个或多个设备。
[0104] 系统存储器1630和大容量存储1650可包括或其中存储有操作系统1660、一个或多个方面应用程序1662、一个或多个方面程序模块1664和数据1666。操作系统1660用于控制和分配计算机1610的资源。应用程序1662包括系统和应用软件中的一个或两者,并且可通过存储在系统存储器1630和/或大容量存储1650中的程序模块1664和数据1666来利用操作系统1660对资源的惯例以执行一个或多个动作。因此,应用程序1662可根据由此提供的逻辑来将通用计算机1610变成专用机器。
[0105] 所要求保护的主题的全部或各部分可以使用产生控制计算机以实现所公开的功能的软件、固件、硬件或其任意组合的标准编程和/或工程技术来实现。作为示例而非限制,工作流引擎110可以是应用程序1662或应用程序1662的一部分,并且包括存储在存储器和/或大容量存储1450中的一个或多个模块1664和数据1666,其功能可以在由如图所示的一个或多个处理器或处理单元1620执行时实现。
[0106] 计算机1610还包括通信地耦合到总线1640并帮助与计算机1610的交互的一个或多个接口组件1670。作为示例,接口组件1670可以是端口(例如,串行、并行、PCMCIA、USB、火线……)或接口卡(例如,声音、视频……)等等。在一个示例实现中,接口组件1670可被具体化为用户输入/输出接口,该用户输入/输出接口使得用户能够通过一个或多个输入设备(例如,诸如鼠标等定点设备、跟踪球、指示笔、触摸垫、键盘、话筒、操纵杆、游戏手柄、圆盘式卫星天线、扫描仪、照相机、其他计算机……)来将命令和信息输入到计算机1610中。在另一示例实现中,接口组件1670可被具体化为输出外围接口,该输出外围接口向显示器(例如,CRT、LCD、等离子……)、扬声器、打印机和/或其他计算机等提供输出。此外,接口组件1670可被具体化为网络接口,该网络接口使得能够诸如通过有线或无线通信链路与其他计算设备(未示出)通信。
[0107] 以上所已经描述的内容包括所要求保护的主题的各方面的示例。当然,出于描绘所要求保护的主题的目的而描述每一个可以想到的组件或方法的组合是不可能的,但本领域内的普通技术人员应该认识到,所要求保护的主题的许多进一步的组合和排列都是可能的。从而,所公开的主题旨在涵盖落入所附权利要求书的精神和范围内的所有这样的变更、修改和变化。