• workflow engine Ruote初体验之三(条件与美元符号)


    • 条件

          我们可以用:if和:unless公共属性来进行条件判断,或者使用if,given,once或者equals(已经过时)关键字。

         使用:if属性:      

    1 cursor do
    2   participant 'customer'
    3   rewind :if => '${not_enough_info} == true'
    4   participant 'logistics'
    5 end

        当使用given表达式的时候:

     1 given do
     2   that "${location} == paris" do
     3     subprocess "notify_and_wait_for_pickup"
     4   end
     5   that "${state} == ready" do
     6     subprocess "deliver"
     7   end
     8   # else...
     9   subprocess "do_something_else"
    10 end

    看起来就是和which case的语法是一样的。given类似于which关键字,that类似于case关键字。当然在:if和:unless可以接收判断条件可以涉及到<,>,<= ,>=等。这个大家很熟悉了。只要能够返回true或者false就可以了。

    • 美元符号 

        在我们以前所举的例子当中,把每个参与者或者每个子流程都写成固定的,就是这个样子:

    1 sequence do
    2   participant 'alfred'
    3   participant 'bob'
    4 end

    但是在真正项目中使用的时候,参与者大都是一个动态的变量。应该是这样的:

    1 sequence do
    2   participant '${f:student}'
    3   participant '${f:teacher}'
    4 end

       根据这个小例子的定义,我们可以看出这个工作流是从学生到老师,学生的真实姓名是存在这个工作流中的student字段,老师的具体名字是存放在工作条目中teacher字段中。

       美元符号获取process的定义的${...}变量,或者在参与者中设置的process的变量。看下面的例子:

     1 require 'ruote'
     2 
     3 # 定义一个引擎
     4 
     5 engine = Ruote::Dashboard.new(
     6     Ruote::Worker.new(
     7         Ruote::HashStorage.new()))
     8 
     9 # 注册参与者
    10 
    11 engine.register_participant :alpha do |workitem|
    12   workitem.fields['message'] =  'Dollar notation Test'
    13 end
    14 
    15 engine.register_participant :bravo do |workitem|
    16   puts "I received a message from #{workitem.fields['message']}"
    17 end
    18 
    19 # 定义一个程序
    20 
    21 pdef = Ruote.define :name => 'test' do
    22   sequence do
    23     set 'f:a' => 'Steven'
    24     echo '${a}'
    25     participant :alpha
    26     echo '${message}'
    27     participant :bravo
    28   end
    29 end
    30 
    31 # 创建一个进程实例
    32 
    33 wfid = engine.launch(pdef)
    34 
    35 engine.wait_for(wfid)

    查看输出结果:

    1 Steven
    2 Dollar notation Test
    3 I received a message from Dollar notation Test

    其中sequence表达式是指注册的参与者按照顺序依次执行。

       变量和工作流中的字段:

       workitem字段对于process实例最为常见,每一个workitem都有一个字段的集合,workitem和字段对于参与者可见。Process变量对于engine以外不可见,只是给route用来在process实例中做逻辑处理用。

     1 Ruote.process_definition :name => 'loan_approval', :revision => '1' do
     2   cursor do
     3     participant 'planning team'
     4     concurrence do
     5       participant 'ceo', :if => '${f:total} > 100000'
     6       participant 'cfo'
     7     end
     8     rewind :unless => '${f:approved}'
     9     participant 'execution team'
    10   end
    11 end

          这个例子的process定义中,有两个字段可见,分别是total和approved。total由'planning team'设置,approved由'ceo'或者'cfo'设置。如果total大于100000,ceo和cfo都收到一个workitem。这两个参与者是并行执行的。

        一直都在说workitem的fields,下面来开一下程序变量的使用方法,只是process定义部分的代码其他同上:

    pdef = Ruote.define :name => 'test' do
        set 'v:test' => 'process var'
        echo '${v:test}'
     end

    输出结果:

    1 process var

      程序变量使用的情况不多,所以在我们写${xx}其实默认表达的是${f:xx}

           还有一些稍微复杂一点的用法比如交叉或者带有复杂的key值,但是用法没有什么不一样。下面看一下workitem字段和process 变量的初始化的问题: 

     1 require 'ruote'
     2 
     3 # preparing the engine
     4 
     5 engine = Ruote::Dashboard.new(
     6     Ruote::Worker.new(
     7         Ruote::HashStorage.new()))
     8 
     9 # registering participants
    10 
    11 engine.register_participant :alpha do |workitem|
    12   workitem.fields['message'] += ' via alpha '
    13 end
    14 
    15 engine.register_participant :bravo do |workitem|
    16   puts "I received a message  #{workitem.fields['message']}"
    17 end
    18 
    19 # defining a process
    20 
    21 pdef = Ruote.define :name => 'test' do
    22     set 'field:message' => 'Helllo'
    23     sequence do
    24       participant :alpha
    25       participant :bravo
    26     end
    27 end
    28 
    29 # launching, creating a process instance
    30 
    31 wfid = engine.launch(pdef)
    32 
    33 engine.wait_for(wfid)

    输出结果:

    1 I received a message  Helllo via alpha 

    在这个例子中,我们初始化了一个workitemfiled,还有没有其他办法呢?我们看一下Dashboar的lauch方法定义

    1 launch(process_definition, fields={}, variables={}, root_stash=nil)

    好吧我们可以这程序运行的时候生成workitem fileds和程序变量,将上面的程序做一点修改:

     1 require 'ruote'
     2 
     3 # preparing the engine
     4 
     5 engine = Ruote::Dashboard.new(
     6     Ruote::Worker.new(
     7         Ruote::HashStorage.new()))
     8 
     9 # registering participants
    10 
    11 engine.register_participant :alpha do |workitem|
    12   workitem.fields['message'] += ' via alpha '
    13 end
    14 
    15 engine.register_participant :bravo do |workitem|
    16   puts "I received a message  #{workitem.fields['message']}"
    17 end
    18 
    19 # defining a process
    20 
    21 pdef = Ruote.define :name => 'test' do
    22     sequence do
    23       participant :alpha
    24       participant :bravo
    25     end
    26 end
    27 
    28 # launching, creating a process instance
    29 
    30 wfid = engine.launch(pdef,'message'=>'Hello')
    31 
    32 engine.wait_for(wfid)

    输出结果:

    1 I received a message  Hello via alpha 

    同样可以。

  • 相关阅读:
    用confluence完成室项目管理网站的初步搭建
    初中英语单词词库 for supermemo
    用supermemo背单词4年了
    武汉一点印象
    借个iPad玩玩,越狱4.2.1成功
    TIOBE在2011年3月发布的编程语言排名表
    复杂的工作机构,一把手真是不易
    自己做的项目竟然与马拉松石油公司的数字油田思路惊人的相似!
    iPhone开发笔记[1/50]:初学iPhone上用Quartz 2D画图
    背单词的词条终于达到6500
  • 原文地址:https://www.cnblogs.com/fantiantian/p/3470935.html
Copyright © 2020-2023  润新知