首页 文章 精选 留言 我的

精选列表

搜索[通用教育],共10006篇文章
优秀的个人博客,低调大师

Openstack 实现技术分解 (4) 通用技术 — TaskFlow

目录 目录 前文列表 扩展阅读 简介 基本概念 实现样例 最后 前文列表 Openstack 实现技术分解 (1) 开发环境 — Devstack 部署案例详解 Openstack 实现技术分解 (2) 虚拟机初始化工具 — Cloud-Init & metadata & userdata Openstack 实现技术分解 (3) 开发工具 — VIM & dotfiles 扩展阅读 TaskFlow 代码库 TaskFlow 文档 简介 TaskFlow is a Python library that helps to make task execution easy, consistent and reliable. A library to do [jobs, tasks, flows] in a highly available, easy to understand and declarative manner (and more!) to be used with OpenStack and other projects. 简而言之, TaskFlow 能够控制应用程序中的长流程业务逻辑任务的暂停、重启、恢复以及回滚, 主要用于保证长流程任务执行的可靠性和一致性。 主要应用场景有如 Cinder 的 create volume 这般复杂、冗长、容易失败, 却又要求保持数据与环境一致的业务逻辑. 从 create volume 流程图看, Cinder 在 create_volume.py(cinder/volume/flows/manager/create_volume.py) 模块中定义了大量的 Tasks class 来组成 TaskFlow: OnFailureRescheduleTask ExtractVolumeRefTask ExtractVolumeSpecTask NotifyVolumeActionTask CreateVolumeFromSpecTask CreateVolumeOnFinishTask 如果在执行任务流的过程中失败了, TaskFlow 的回滚机制能够让程序流和执行环境回滚到初始状态, 并且可以重新开始执行. 总的来说, TaskFlow 非常适合于 面向任务 的应用场景. 基本概念 Atom: An atom is the smallest unit in TaskFlow which acts as the base for other classes Atom: Atom 是 TaskFlow 的最小单位, 其他的所有类, 包括 Task 类都是 Atom 类的子类. Task: A task (derived from an atom) is a unit of work that can have an execute & rollback sequence associated with it (they are nearly analogous to functions). Task: task 是拥有执行和回滚功能额最小工作单元. 在 Task 类中开发者能够自定义 execute(执行) 和 revert(回滚) method. Flow: Linear/Unordered/Graph Flow: 在 TaskFlow 中使用 flow(流) 来关联各个 Task, 并且规定这些 Task 之间的执行和回滚顺序. flow 中不仅能够包含 task 还能够嵌套 flow. 常见类型有以下几种: Linear(linear_flow.Flow): 线性流, 该类型 flow 中的 task/flow 按照加入的顺序来依次执行, 按照加入的倒序依次回滚. Unordered(unordered_flow.Flow): 无序流, 该类型 flow 中的 task/flow 可能按照任意的顺序来执行和回滚. Graph(graph_flow.Flow): 图流, 该类型 flow 中的 task/flow 按照显式指定的依赖关系或通过其间的 provides/requires 属性的隐含依赖关系来执行和回滚. Retry: A retry (derived from an atom) is a special unit of work that handles errors, controls flow execution and can (for example) retry other atoms with other parameters if needed. Retry: Retry 是一个控制当错误发生时, 如何进行重试的特殊工作单元, 而且当你需要的时候还能够以其他参数来重试执行别的 Atom 子类. 常见类型: AlwaysRevert: 错误发生时, 回滚子流 AlwaysRevertAll: 错误发生时, 回滚所有流 Times: 错误发生时, 重试子流 ForEach: 错误发生时, 为子流中的 Atom 提供一个新的值, 然后重试, 直到成功或 retry 中定义的值用完为止. ParameterizedForEach: 错误发生时, 从后台存储(由 store 参数提供)中获取重试的值, 然后重试, 直到成功或后台存储中的值用完为止. Engine: Engines are what really runs your atoms. Engine: Engines 才是真正运行 Atoms 的对象, 用于 load(载入) 一个 flow, 然后驱动这个 flow 中的 task/flow 开始运行. 我们可以通过 engine_conf 参数来指定不同的 engine 类型. 常见的 engine 类型如下: serial: 所有的 task 都在调用了 engine.run 的线程中运行. parallel: task 可以被调度到不同的线程中运行. worker-based: task 可以被调度到不同的 woker 中运行. 实现样例 源码请浏览 Github #!/usr/bin/env python #filename: tasks.py import taskflow.engines from taskflow.patterns import linear_flow as lt from taskflow import task from taskflow.types import failure as task_failed class CallJim(task.Task): default_provides = set(['jim_new_number']) def execute(self, jim_number, *args, **kwargs): print "Calling Jim %s." % jim_number print '=' * 10 jim_new_number = jim_number + 'new' return {'jim_new_number': jim_new_number} def revert(self, result, *args, **kwargs): if isinstance(result, task_failed.Failure): print "jim result" return None jim_new_number = result['jim_new_number'] print "Calling jim %s and apologizing." % jim_new_number class CallJoe(task.Task): default_provides = set(['joe_new_number', 'jim_new_number']) def execute(self, joe_number, jim_new_number, *args, **kwargs): print "Calling jim %s." % jim_new_number print "Calling Joe %s." % joe_number print '=' * 10 joe_new_number = joe_number + 'new' return {'jim_new_number': jim_new_number, 'joe_new_number': joe_new_number} def revert(self, result, *args, **kwargs): if isinstance(result, task_failed.Failure): print "joe result" return None jim_new_number = result['jim_new_number'] joe_new_number = result['joe_new_number'] print "Calling joe %s and apologizing." % joe_new_number class CallJmilkFan(task.Task): default_provides = set(['new_numbers']) def execute(self, jim_new_number, joe_new_number, jmilkfan_number, *args, **kwargs): print "Calling jim %s" % jim_new_number print "Calling joe %s" % joe_new_number print "Calling jmilkfan %s" % jmilkfan_number print '=' * 10 jmilkfan_new_number = jmilkfan_number + 'new' raise ValueError('Error') new_numbers = {'jim_new_number': jim_new_number, 'joe_new_number': joe_new_number, 'jmilkfan_new_number': jmilkfan_new_number} return {'new_numbers': new_numbers} def revert(self, result, *args, **kwargs): if isinstance(result, task_failed.Failure): print "jmilkfan result" return None jim_new_number = result['jim_new_number'] joe_new_number = result['joe_new_number'] jmilkfan_new_number = result['jmilkfan_new_number'] print "Calling jmilkfan %s and apologizing." % jmilkfan_new_number def get_flow(flow, numbers): flow_name = flow flow_api = lt.Flow(flow_name) flow_api.add(CallJim(), CallJoe(), CallJmilkFan()) return taskflow.engines.load(flow_api, engine_conf={'engine': 'serial'}, store=numbers) def main(): numbers = {'jim_number': '1'*6, 'joe_number': '2'*6, 'jmilkfan_number': '3'*6} try: flow_engine = get_flow(flow='taskflow-demo', numbers=numbers) flow_engine.run() except Exception: print "TaskFlow Failed!" raise new_numbers = flow_engine.storage.fetch('new_numbers') if __name__ == '__main__': main() Output: fanguiju@fanguiju:~/project/my-code-repertory/TaskFlow-demo$ python tasks.py Calling Jim 111111. ========== Calling jim 111111new. Calling Joe 222222. ========== Calling jim 111111new Calling joe 222222new Calling jmilkfan 333333 ========== jmilkfan result Calling joe 222222new and apologizing. Calling jim 111111new and apologizing. TaskFlow Failed! Traceback (most recent call last): File "tasks.py", line 114, in <module> main() File "tasks.py", line 105, in main flow_engine.run() File "/usr/local/lib/python2.7/dist-packages/taskflow/engines/action_engine/engine.py", line 159, in run for _state in self.run_iter(): File "/usr/local/lib/python2.7/dist-packages/taskflow/engines/action_engine/engine.py", line 223, in run_iter failure.Failure.reraise_if_any(it) File "/usr/local/lib/python2.7/dist-packages/taskflow/types/failure.py", line 292, in reraise_if_any failures[0].reraise() File "/usr/local/lib/python2.7/dist-packages/taskflow/types/failure.py", line 299, in reraise six.reraise(*self._exc_info) File "/usr/local/lib/python2.7/dist-packages/taskflow/engines/action_engine/executor.py", line 82, in _execute_task result = task.execute(**arguments) File "tasks.py", line 66, in execute raise ValueError('Error') ValueError: Error NOTE 1: 在 function get_flow 中使用 linear_flow.Flow 生成一个 TaskFlow(线性任务流) 对象 flow_api , 再通过flow_api.add method 添加要 顺序执行且倒序回滚 的 Task class(CallJim/CallJom/CallJmilkFan). NOTE 2: 使用 taskflow.engines.load method 来加载 TaskFlow(flow_api)对象/后台存储数据(store)/ engine配置 等信息并生成 Task Engine 对象. NOTE 3: 最后调用 Task Engine 对象的 flow_engine.run method 来开始执行该任务流. NOTE 4: 后台存储 store 的数据在该任务流中被所有 Task class 共享, 并且以 Task class 中的 execute method 的形参作为对接入口. e.g. 上述实现的 store 后台存储中含有 {jim_number: '1'*6}, 那么 CallJim 的 execute method 就可以通过形参 jim_number 来获取 '1'*6 的值. NOTE 5: Task class 的属性 default_provides 用于声明在执行过程中新添到后台存储的元素的名称, 其相应的值会自动的从 execute method 返回值中匹配获取, 最终存储后台存储. e.g. CallJim 的属性 default_provides = set(['jim_new_number']) 其中 jim_new_number 的值会从 execute method 的返回 return {'jim_new_number': jim_new_number} 中获取. NOTE 6: provides 的实现能够有效的帮助传递 Task class 之间在执行时产生的新属性对象. 将上一个 Task 的结果传递给后一个 Task 使用. 最后 当实现的 TaskFlow 中包含了多个 Task(的确可能存在只有一个 Task 的 TaskFlow) 时, 有两点是需要注意的: 在使用线性流类型的 TaskFlow 时, Task class revert method 回滚的应该是上一个 Task class execute method 的业务. e.g. BTask.revert 应该回滚 ATask.execute, 因为只有在 ATask.execute 成功执行的前提之下才有 revert 的价值. 所以在 revert method 的定义中需要实现语句 if isinstance(result, task_failed.Failure): return None. 当一个 Task 的 execute method 执行失败时, 那么 revert method 接收的 result 实参就是 taskflow.types.failure.Failure 的实例对象. 尽量让每个 Task class 都仅处理一件事情, 这是为了让每一次回滚都足够精准. e.g. 尽管创建虚拟机和开启虚拟机都同属于对虚拟机的操作, 但是我们仍然应该将两者各自定义一个 Task class. 假如启动虚拟机失败时, 我们只需再次重试启动虚拟机, 而无须再次重复创建虚拟机.

优秀的个人博客,低调大师

PlayEdu v1.0-beta.6 发布,视频教育解决方案

官网:https://playedu.xyz PlayEdu 是基于 SpringBoot3 + Java17 + React18 开发的企业内部培训系统。它专注于提供私有化部署方案,包括视频,图片等资源的内网部署。目前主要支持有本地视频上传播放、学员邮箱登录、无限级部门、无限级资源分类、学员在线学习等主要功能。 更新 优化MinIO配置 优化图形验证码 优化学员删除的关联数据删除 优化 dockerfile 新增:禁止拖拽播放配置 源代码 https://gitee.com/playeduxyz/playedu https://github.com/playedu/playedu 页面展示

优秀的个人博客,低调大师

PlayEdu v1.0-beta.5 发布,视频教育解决方案

官网:https://playedu.xyz PlayEdu 是基于 SpringBoot3 + Java17 + React18 开发的企业内部培训系统。它专注于提供私有化部署方案,包括视频,图片等资源的内网部署。目前主要支持有本地视频上传播放、学员邮箱登录、无限级部门、无限级资源分类、学员在线学习等主要功能。 更新 学员注册增加课程分类筛选 线上课-学员列表增加学员所属部门、邮箱字段的显示 线上课-学员列表显示可以观看该线上课的所有学员 修复学员的多部门查询bug 优化学员学习进度的展示(前后台保持统一) 修复后台部门的文案显示溢出 优化视频播放页面样式和交互 源代码 https://gitee.com/playeduxyz/playedu https://github.com/playedu/playedu 页面展示

优秀的个人博客,低调大师

uexam v3.8.0 发布,在线教育学习考试系统

学之思简介: 学之思开源考试系统是一款 java + vue 的前后端分离的考试系统。主要优点是开发、部署简单快捷、界面设计友好、代码结构清晰。支持 web 端和微信小程序,能覆盖到 pc 机和手机等设备。 支持多种部署方式:集成部署、前后端分离部署、docker 部署。 本次更新内容: 1. 升级前端node版本至16,兼容v12-v16版本 2. 升级element ui框架版本 3. 修复微信小程序兼容问题 4. 修复部分系统登录失败问题 5. 接口、教程文档更新 学生端功能: 模块 介绍 登录 用户名、密码 注册 年级、用户名、密码 任务中心 管理员发布的年级任务,每个学生只能做一次 考试 题干支持文本、图片、数学公式、表格等,学生答题支持:文本 固定试卷 可重复练习、自行批改的试卷 时段试卷 在时间限制内,可重复练习、自行批改的试卷 考试记录 查看答卷记录和试卷信息 错题本 答错题目会自动进入错题本,显示题目基本信息 个人信息 显示学生个人资料 更新信息 修改个人资料、头像 个人动态 显示用户最近的个人动态 消息中心 用于接收管理员发送的消息 管理端功能: 模块 介绍 登录 用户名、密码 主页 试卷总数、题目总数、用户活跃度、题目月数量 学生列表 显示系统所有的学生,新增、修改、删除、禁用 管理员列表 显示系统所有的管理员,新增、修改、删除、禁用 学科列表 学科查询、修改、删除 学科创编 创建学科 试卷列表 试卷查询、修改、删除 试卷创编 创建的试卷为时段试卷、固定试卷、任务试卷 题目列表 题目查询、修改、删除 题目创建 题目支持单选题、多选题、判断题、填空题、简答题,题干支持文本、图片、表格、数学公式 任务列表 任务查询、修改、删除 消息列表 显示已发送的消息,消息已读人数等信息 消息发送 发送消息给多个用户 用户日志 显示所有用户日志 个人资料 显示管理员用户名、真实姓名 时间线 显示管理员创建时间 修改资料 修改姓名、手机号 小程序功能: 模块 介绍 登录 用户登录登出功能,登录会自动绑定微信账号,登出会解绑 注册 年级、用户名、密码 任务中心 管理员发布的年级任务,每个学生只能做一次 考试 题干支持文本、图片、数学公式、表格等,学生答题支持:文本 固定试卷 可重复练习、自行批改的试卷 时段试卷 在时间限制内,可重复练习、自行批改的试卷 考试记录 查看答卷记录和试卷信息 错题本 答错题目会自动进入错题本,显示题目基本信息 个人信息 显示学生个人资料 更新信息 修改个人资料、头像 个人动态 显示用户最近的个人动态 消息中心 用于接收管理员发送的消息

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册