目录
1.创建一个yaml文件,名字可以是student.yaml
欢迎关注公众号:天天说编程
你的关注是我最大的动力!
本文章内容,只是一个简单的案例,但足够映射到一个大的项目中。
工作流作用:工作流的作用就是通过yaml配置文件,将关于本工作流的一个个task任务串联起来形成一个大的功能体。通过加载yaml,将任务执行的顺序固定化。
说白了就是对任务进行编排,当大流量来的时候,可以让线程排队执行。
比如:用户注册,需要验证哪些参数,比如验证邮件地址,验证手机号,可以把这些小功能放到一个小任务中,也就是task。然后将这些任务串起来,形成一个大功能,也就是工作流。
现在举个具体的案例,来实现一个简易的工作流,更加通俗易懂。
这里举了一个用户注册的功能。
yaml都是key:value结构。- 代表的是一个数组,数组中的元素是key:value结构,这个value还可以是数组类型等等。
- # 工作流名字
- workflow: "user"
-
- # 具体执行的任务
- tasks:
- # 邮件地址的有效性
- # 单斜杠后面 - 后面是一个列表
- # name:task的名字
- # action:具体task对应的方法
- # params:相关参数,这个参数可能是前端传来的,需要取出,也可能是上一个task的结果。
- # requires:这个任务是否有依赖,也就是这个任务执行的时候需要执行的另一个任务。
-
- - name: "validate_email"
- action: "validate_email_action"
- params:
- email: "user@example.com"
- requires: []
-
- - name: "create_user"
- action: "create_user_action"
- params:
- "username": "yaml"
- "password": "123456"
-
- # 这儿创建用户的时候需要验证邮件地址是否有效
- requires:
- - "validate_email"
-
- - name: "send_welcome_email"
- action: "send_welcome_email_action"
- params:
- "recipient": "user@example.com"
- "subject": "Welcome to our platform!"
- "body":
- "Dear John Doe,
- Welcome to our platform! We are excited to have you on board.
- Best regards,
- The Team"
- # 发送这个welcome消息的时候,代表创建成功。
- "requires":
- - "create_user"
创建一个main.go
- package main
-
- import (
- "fmt"
- "gopkg.in/yaml.v3"
- "io/ioutil"
- )
- // Workflow 结构体
- type Workflow struct {
- Name string `yaml:"workflow"`
- Tasks []Task `yaml:"tasks"`
- }
-
- // Task 结构体
- type Task struct {
- Name string `yaml:"name"`
- Action string `yaml:"action"`
- Params map[string]any `yaml:"params"`
- Requires []string `yaml:"requires"`
- }
-
- func main() {
- data, err := ioutil.ReadFile("workflow/student.yml")
- if err != nil {
- fmt.Println("读取配置文件失败:", err)
- return
- }
-
- var workflow Workflow
- // yaml反序列化,将字节类型的数据反序列化到结构体中
- err = yaml.Unmarshal(data, &workflow)
- if err != nil {
- fmt.Println("data反序列化错误:", err)
- return
- }
-
- // 执行工作流的任务
- // 获取工作流
- for _, task := range workflow.Tasks {
- if checkDependecies(task.Requires) {
- fmt.Println("执行任务", task.Name)
- result, err := executeTask(task.Action, task.Params)
- if err != nil {
- fmt.Println("任务执行失败!", err)
- return
- }
- fmt.Println("执行的结果为:", result)
- fmt.Println("---")
- } else {
- fmt.Println("跳过任务:", task.Name)
- }
- fmt.Println("task.Params:", task.Params)
- fmt.Println("task.Action:", task.Action)
- fmt.Println("task.Requires:", task.Requires)
- fmt.Println("task.Name:", task.Name)
- if task.Params["username"] != "" {
- fmt.Println("task.Params username:", task.Params["username"])
- }
- }
- fmt.Println("用户执行成功!~")
-
- }
-
- // 检查任务的依赖是否满足
- func checkDependecies(requires []string) bool {
- // todo 验证参数
- return true
- }
- // 执行任务
- func executeTask(action string, params map[string]any) (string, error) {
- switch action {
- case "validate_email_action":
- // todo 验证邮件地址的有效性
- return "ok", nil
- case "create_user_action":
- //todo 创建用户
- return "user_id", nil
- case "send_welcome_email_action":
- // 发送消息
- return "ok", nil
- default:
- return "", fmt.Errorf("未知的任务:%s", action)
- }
- }
我把参数信息都打印出来了
- 执行任务 validate_email
- 执行的结果为: ok
- ---
- task.Params: map[email:user@example.com]
- task.Action: validate_email_action
- task.Requires: []
- task.Name: validate_email
- task.Params username: <nil>
- 执行任务 create_user
- 执行的结果为: user_id
- ---
- task.Params: map[password:123456 username:yaml]
- task.Action: create_user_action
- task.Requires: [validate_email]
- task.Name: create_user
- task.Params username: yaml
- 执行任务 send_welcome_email
- 执行的结果为: ok
- ---
- task.Params: map[body:Dear John Doe, Welcome to our platform! We are excited to
- have you on board. Best regards, The Team recipient:user@example.com subject:Wel
- come to our platform!]
- task.Action: send_welcome_email_action
- task.Requires: [create_user]
- task.Name: send_welcome_email
- task.Params username: <nil>
- 用户执行成功!~
欢迎关注公众号:天天说编程
你的关注是我最大的动力!