Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

工作流的定义可以修改吗 #27

Open
jiyarong opened this issue Aug 2, 2022 · 29 comments
Open

工作流的定义可以修改吗 #27

jiyarong opened this issue Aug 2, 2022 · 29 comments

Comments

@jiyarong
Copy link

jiyarong commented Aug 2, 2022

比如你seed.rb里的定义,deploy之后,我以后中间想继续插流程,可以吗

@jasl
Copy link
Member

jasl commented Aug 2, 2022

seed.rb 里的代码是利用我提供的 DSL 去定义 Petrinet,所以你执行后会产生一个新 Workflow,不会替代已有的

@jiyarong
Copy link
Author

jiyarong commented Aug 4, 2022

问一个设计上的问题,很显然在一个erp系统里,一个workflow走到不同的环节所要完成的task肯定是大相径庭的,我是否应该为所有的transition定义不同的trigger,还是所有transition用相同的trigger,然后根据workflow目前走到的位置去下发不同的task。还有就是一个transition如果没有trigger,从业务层来说感觉就和workflow失联了 @jasl

@jasl
Copy link
Member

jasl commented Aug 4, 2022

问一个设计上的问题,很显然在一个erp系统里,一个workflow走到不同的环节所要完成的task肯定是大相径庭的,我是否应该为所有的transition定义不同的trigger,还是所有transition用相同的trigger,然后根据workflow目前走到的位置去下发不同的task。还有就是一个transition如果没有trigger,从业务层来说感觉就和workflow失联了

每个 transition 应该有不同的trigger,因为这一步骤的流转配置是配置在 trigger 上的,虽然绝大多数步骤都是相似的,但是审批人之类的条件信息还是不同的,如果多个 transition 共享一个trigger,如果trigger 被修改,引发的对流程的破坏会更大

@jiyarong
Copy link
Author

jiyarong commented Aug 12, 2022

我想请教一下,审批驳回的逻辑,也就是你之前例子里面ltractive routing,用DSL怎么配出来,是在某个节点,output两个place,一个指向后面的place,一个指向前面的place,然后通过ArcGuard来判断去哪吗

FlowCore::Definition.new name: "Simple sequence" do |net|
  net.start_place :start, name: "Start"
  net.end_place :end, name: "End"

  net.transition :t1, input: :start, output: :p1
  net.transition :t2, input: :p1, output: %i[start end]
end.deploy!

@jasl

@jasl
Copy link
Member

jasl commented Aug 12, 2022

我想请教一下,审批驳回的逻辑,也就是你之前例子里面ltractive routing,用DSL怎么配出来,是在某个节点,output两个place,一个指向后面的place,一个指向前面的place,然后通过ArcGuard来判断去哪吗

FlowCore::Definition.new name: "Simple sequence" do |net|
  net.start_place :start, name: "Start"
  net.end_place :end, name: "End"

  net.transition :t1, input: :start, output: :p1
  net.transition :t2, input: :p1, output: %i[start end]
end.deploy!

@jasl

先稍等啊,我手头有点事要出门一趟,我晚上到家回复你。。。

@jasl
Copy link
Member

jasl commented Aug 12, 2022

我想请教一下,审批驳回的逻辑,也就是你之前例子里面ltractive routing,用DSL怎么配出来,是在某个节点,output两个place,一个指向后面的place,一个指向前面的place,然后通过ArcGuard来判断去哪吗

FlowCore::Definition.new name: "Simple sequence" do |net|
  net.start_place :start, name: "Start"
  net.end_place :end, name: "End"

  net.transition :t1, input: :start, output: :p1
  net.transition :t2, input: :p1, output: %i[start end]
end.deploy!

@jasl

你要在哪年的RubyConfChina微信群可以加我好友,这样有问题问我更方便

@jiyarong
Copy link
Author

我想请教一下,审批驳回的逻辑,也就是你之前例子里面ltractive routing,用DSL怎么配出来,是在某个节点,output两个place,一个指向后面的place,一个指向前面的place,然后通过ArcGuard来判断去哪吗

FlowCore::Definition.new name: "Simple sequence" do |net|
  net.start_place :start, name: "Start"
  net.end_place :end, name: "End"

  net.transition :t1, input: :start, output: :p1
  net.transition :t2, input: :p1, output: %i[start end]
end.deploy!

@jasl

先稍等啊,我手头有点事要出门一趟,我晚上到家回复你。。。

多谢了

@jiyarong
Copy link
Author

问一个设计上的问题,很显然在一个erp系统里,一个workflow走到不同的环节所要完成的task肯定是大相径庭的,我是否应该为所有的transition定义不同的trigger,还是所有transition用相同的trigger,然后根据workflow目前走到的位置去下发不同的task。还有就是一个transition如果没有trigger,从业务层来说感觉就和workflow失联了

每个 transition 应该有不同的trigger,因为这一步骤的流转配置是配置在 trigger 上的,虽然绝大多数步骤都是相似的,但是审批人之类的条件信息还是不同的,如果多个 transition 共享一个trigger,如果trigger 被修改,引发的对流程的破坏会更大

如果要为每个transition定义不同的trigger,我应该继承你哪个类,实现什么方法,才能达成这样的效果

@jasl
Copy link
Member

jasl commented Apr 25, 2024

问一个设计上的问题,很显然在一个erp系统里,一个workflow走到不同的环节所要完成的task肯定是大相径庭的,我是否应该为所有的transition定义不同的trigger,还是所有transition用相同的trigger,然后根据workflow目前走到的位置去下发不同的task。还有就是一个transition如果没有trigger,从业务层来说感觉就和workflow失联了

每个 transition 应该有不同的trigger,因为这一步骤的流转配置是配置在 trigger 上的,虽然绝大多数步骤都是相似的,但是审批人之类的条件信息还是不同的,如果多个 transition 共享一个trigger,如果trigger 被修改,引发的对流程的破坏会更大

如果要为每个transition定义不同的trigger,我应该继承你哪个类,实现什么方法,才能达成这样的效果

默认似乎就是 “为每个transition定义不同的trigger”,Transition has one Trigger
https://github.com/rails-engine/flow_core/blob/master/app/models/flow_core/transition.rb#L24

Transition trigger 的例子参考参考 Dummy app 比如人工审批
https://github.com/rails-engine/flow_core/blob/master/test/dummy/app/models/flow_kit/transition_triggers/human_task.rb

@jiyarong
Copy link
Author

jiyarong commented Apr 25, 2024

问一个设计上的问题,很显然在一个erp系统里,一个workflow走到不同的环节所要完成的task肯定是大相径庭的,我是否应该为所有的transition定义不同的trigger,还是所有transition用相同的trigger,然后根据workflow目前走到的位置去下发不同的task。还有就是一个transition如果没有trigger,从业务层来说感觉就和workflow失联了

每个 transition 应该有不同的trigger,因为这一步骤的流转配置是配置在 trigger 上的,虽然绝大多数步骤都是相似的,但是审批人之类的条件信息还是不同的,如果多个 transition 共享一个trigger,如果trigger 被修改,引发的对流程的破坏会更大

如果要为每个transition定义不同的trigger,我应该继承你哪个类,实现什么方法,才能达成这样的效果

默认似乎就是 “为每个transition定义不同的trigger”,Transition has one Trigger https://github.com/rails-engine/flow_core/blob/master/app/models/flow_core/transition.rb#L24

Transition trigger 的例子参考参考 Dummy app 比如人工审批 https://github.com/rails-engine/flow_core/blob/master/test/dummy/app/models/flow_kit/transition_triggers/human_task.rb

你这HumanTask继承Trigger,就是在on_task_enable中决定下发什么任务,这和我之前理解的用法是一样的,你意思这种做法就是为每个任务定义不同的trigger了吗,我以为比如还有human2Task,human3Task

@jiyarong
Copy link
Author

非常抱歉两年后还来打扰你,我们的业务经过两年的发展后,流程趋于稳定,但流程复杂度非常高,不找个这样的库不太行了

车辆交付流程图 (1)

@jasl
Copy link
Member

jasl commented Apr 25, 2024

问一个设计上的问题,很显然在一个erp系统里,一个workflow走到不同的环节所要完成的task肯定是大相径庭的,我是否应该为所有的transition定义不同的trigger,还是所有transition用相同的trigger,然后根据workflow目前走到的位置去下发不同的task。还有就是一个transition如果没有trigger,从业务层来说感觉就和workflow失联了

每个 transition 应该有不同的trigger,因为这一步骤的流转配置是配置在 trigger 上的,虽然绝大多数步骤都是相似的,但是审批人之类的条件信息还是不同的,如果多个 transition 共享一个trigger,如果trigger 被修改,引发的对流程的破坏会更大

如果要为每个transition定义不同的trigger,我应该继承你哪个类,实现什么方法,才能达成这样的效果

默认似乎就是 “为每个transition定义不同的trigger”,Transition has one Trigger https://github.com/rails-engine/flow_core/blob/master/app/models/flow_core/transition.rb#L24
Transition trigger 的例子参考参考 Dummy app 比如人工审批 https://github.com/rails-engine/flow_core/blob/master/test/dummy/app/models/flow_kit/transition_triggers/human_task.rb

你这HumanTask继承Trigger,就是在on_task_enable中决定下发什么任务,这和我之前理解的用法是一样的,你意思这种做法就是为每个任务定义不同的trigger了吗,我以为比如还有human2Task,human3Task

因为是通过 has_one 关联的具体的 trigger,所以你直接指向不同的 trigger 记录就能设置不同的了

@jasl
Copy link
Member

jasl commented Apr 25, 2024

非常抱歉两年后还来打扰你,我们的业务经过两年的发展后,流程趋于稳定,但流程复杂度非常高,不找个这样的库不太行了

车辆交付流程图 (1)

欢迎交流,这个库我觉得没过时,表单部分 Rails 8 会有一个官方的虚拟模型方案,所以等 8 出来我可以再维护下

@jasl
Copy link
Member

jasl commented Apr 25, 2024

这个流程我感觉不难,你看看能否通过 dummy app 能否配出来你的流程?

@jiyarong
Copy link
Author

jiyarong commented Apr 25, 2024

这个流程我感觉不难,你看看能否通过 dummy app 能否配出来你的流程?

用你这个理论上是不难,并行合并,再并行,再合并,用aasm是搞不出来,很难用一个单一状态来描述我的货物处于哪个阶段

@jasl
Copy link
Member

jasl commented Apr 25, 2024

这个流程我感觉不难,你看看能否通过 dummy app 能否配出来你的流程?

用你这个理论上是不难,并行合并,再并行,再合并,用aasm是搞不出来

状态机肯定表达不了并行,我记得我20年在 RubyConf China 上分享过不同的工作流的原理的优缺点对比,你可以翻翻~

我这两三年是去做区块链啦,所以就离这个远了

@jiyarong
Copy link
Author

jiyarong commented Apr 25, 2024

你的Demo运行时有错误,不知道是升到rails7的原因,还是我是苹果芯片版的mac

Screenshot 2024-04-25 at 14 49 28

而且你这个生成图的依赖看着就挺吓人,我能否不用你这套,简单的用我部署的workflow的结构,找个其他的画流程图的应用把图画出来,纯前端JS画都行,不知道你有没有相关推荐,编辑流程图好像也没太大必要,有新环节,重新搞一个workflow出来就行了

@jasl
Copy link
Member

jasl commented Apr 25, 2024

你的Demo运行时有错误,不知道是升到rails7的原因,还是我是苹果芯片版的mac

Screenshot 2024-04-25 at 14 49 28 而且你这个生成图的依赖看着就挺吓人,我能否不用你这套,简单的用我部署的workflow的结构,找个其他的画流程图的应用把图画出来,纯前端JS画都行,不知道你有没有相关推荐

这个错误是你没装 graphviz 文档提了
你跑 brew install graphviz 就行了

我懒得写前端而且我也不知道哪个通用,所以用 graphviz 来画了就,丑是丑了点,但是能用

@jasl
Copy link
Member

jasl commented Apr 25, 2024

而且你这个生成图的依赖看着就挺吓人

我不知道你说的是什么,我只提供了 graphviz 的流程图绘制和导出,这是个纯文本格式

@jiyarong
Copy link
Author

兄弟,问个问题,你这个流程能回滚吗,比如到了某一步,发现上一个环节的人数据填错了,这个时候咋办

@jasl
Copy link
Member

jasl commented May 13, 2024

兄弟,问个问题,你这个流程能回滚吗,比如到了某一步,发现上一个环节的人数据填错了,这个时候咋办

需要支持回滚的步骤都加个连接到上一步的流转就好了,包括驳回都是这么支持的

@jiyarong
Copy link
Author

兄弟,你这个arc_guard在配置的时候怎么写的,看的不是太懂

FlowCore::Definition.new name: "Car Process Test" do |net|
  net.start_place :start
  net.end_place :end

  net.transition :a1, input: :start, output: %i[p1 p2] do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
  ...
end.deploy!

比如这个p1,p2分别设置arc_guard怎么写

@jiyarong
Copy link
Author

jiyarong commented May 14, 2024

还有个问题是,比如我的交付流程,有可能最后是“成功交付”,也可能中间某个环节出问题了(比如客户不要了要退款),整个交付要关掉,我就在想,给每个环节加一个arc_guard,出问题了直接走到“交付取消”,那么这个时候“成功交付”和“交付取消”,是2个end_place?还是其实“交付取消”和“交付成功”是一个end_place,不然的话,“交付取消”的流程,整个workflow_instance怎么才能finish

@jasl
Copy link
Member

jasl commented May 14, 2024

还有个问题是,比如我的交付流程,有可能最后是“成功交付”,也可能中间某个环节出问题了,整个交付要关掉,我就在想,给每个环节加一个arc_guard,出问题了直接走到“交付取消”,那么这个时候“成功交付”和“交付取消”,是2个end_place?还是其实“交付取消”和“交付成功”是一个end_place,不然的话,“交付取消”的流程,整个workflow_instance怎么才能finish

时间太久忘记 PetriNet 的定义了,
如果支持两个 end place 的话,交易成功 和 交易成功 就分别是两个 end place,place 你可以理解就是流程的停靠状态
如果不行的话,就是两个 place,然后 transit 到一个 end place

@jiyarong
Copy link
Author

还有个问题是,比如我的交付流程,有可能最后是“成功交付”,也可能中间某个环节出问题了,整个交付要关掉,我就在想,给每个环节加一个arc_guard,出问题了直接走到“交付取消”,那么这个时候“成功交付”和“交付取消”,是2个end_place?还是其实“交付取消”和“交付成功”是一个end_place,不然的话,“交付取消”的流程,整个workflow_instance怎么才能finish

时间太久忘记 PetriNet 的定义了, 如果支持两个 end place 的话,交易成功 和 交易成功 就分别是两个 end place,place 你可以理解就是流程的停靠状态 如果不行的话,就是两个 place,然后 transit 到一个 end place

但是你的定义里面,workflow,has_one: end_place啊

@jasl
Copy link
Member

jasl commented May 14, 2024

如果不行的话,就是两个 place,然后 transit 到一个 end place

如果不行的话,就是两个 place,然后 transit 到一个 end place
后来编辑了一下,时间久了忘记 PetriNet 的定义了,Flow Core 用的原理是 PetriNet,是一种工作流的实现原理,我应该在 RubyConfChina 2020 有分享过几种工作流的实现原理和优缺点介绍,相关知识可以了解下

@jiyarong
Copy link
Author

FlowCore::Definition.new name: "Car Process Test" do |net|
  net.start_place :start
  net.end_place :end

  net.transition :a1, input: :start do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
    t.output :p1, with_guard: { type: FlowCore::ArcGuard }
    t.output :p2
  end
  net.transition :a2, input: :p1, output: :p3 do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
  net.transition :a3, input: :p2, output: :p4 do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
  net.transition :a4, input: %i[p3 p4], output: :end do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
end.deploy!

我看你的源码,感觉是这样配arc_guard吗

@jiyarong
Copy link
Author

FlowCore::Definition.new name: "Car Process Test" do |net|
  net.start_place :start
  net.end_place :end

  net.transition :a1, input: :start do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
    t.output :p1, with_guard: { type: FlowCore::ArcGuard }
    t.output :p2
  end
  net.transition :a2, input: :p1, output: :p3 do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
  net.transition :a3, input: :p2, output: :p4 do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
  net.transition :a4, input: %i[p3 p4], output: :end do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
end.deploy!

我看你的源码,感觉是这样配arc_guard吗

没错就是这样,就是type还得是FlowCore::ArcGuard的子类

@jasl
Copy link
Member

jasl commented May 14, 2024

FlowCore::Definition.new name: "Car Process Test" do |net|
  net.start_place :start
  net.end_place :end

  net.transition :a1, input: :start do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
    t.output :p1, with_guard: { type: FlowCore::ArcGuard }
    t.output :p2
  end
  net.transition :a2, input: :p1, output: :p3 do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
  net.transition :a3, input: :p2, output: :p4 do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
  net.transition :a4, input: %i[p3 p4], output: :end do |t|
    t.with_trigger Ev::CarProcessTransitionTrigger
  end
end.deploy!

我看你的源码,感觉是这样配arc_guard吗

没错就是这样,就是type还得是FlowCore::ArcGuard的子类

是的 因为基类是个抽象类没意义

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants