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 

同樣可以。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM