2017-01-10 3 views
5

バックグラウンドスレッドで順番に実行したいタスクがあります。各タスクの結果は次のスレッドに渡されます。チェーンが失敗する。Concurrent Rubyで一連のタスクを連鎖する

引数として、各タスクが値を返すexecメソッドを持つオブジェクトであるとしましょうが、それらはprocsまたはlambdasと同じくらい良いかもしれませんが。どちらかPromise APIや他の場所で同時Rubyで、

promise = array_of_tasks.inject(nil) do |promise, task| 
      if promise 
       promise.then { |prev_result| task.exec(prev_result) } 
      else 
       Concurrent::Promise.new { task.exec } 
      end 
      end 

promise.on_success { |last_result| log.info("Success: #{last_result} ")} 
promise.rescue { |reason| log.error("Failure: #{reason}")} 

これを行うために、より簡潔な方法があります:

のようなものは、私が今持っているのですか?それはかなり基本的な操作のようですが、私はそれを行う既存の方法を見ていません。

(このような方法がない場合、未来の約束の世界にこのパターンのよく知られた名前がありますか?つまり、自分でメソッドを書くと、 ?

答えて

2

それは短くない)その名前が、この構造は、簡単に新しい機能を追加することになるかもしれない:それはこの方法を使用することができます

require 'concurrent' 

class Task 
    def exec(x = 0) 
    sleep 0.1 
    p x + 1 
    end 

    alias call exec 

    def to_promise(*params) 
    Concurrent::Promise.new { exec(*params) } 
    end 
end 

module PromiseChains 
    refine Concurrent::Promise do 
    def chained_thens(callables) 
     callables.inject(self) do |promise, callable| 
     promise.then do |prev_result| 
      callable.call(prev_result) 
     end 
     end 
    end 
    end 
end 

:OUTP

using PromiseChains 

array_of_tasks = Array.new(10) { Task.new } 

array_of_tasks << ->(x) { p x * 2 } 
array_of_tasks << proc { |x| p x * 3 } 

first_task, *other_tasks = array_of_tasks 

chain = first_task.to_promise.chained_thens(other_tasks) 

chain.on_success { |last_result| puts "Success: #{last_result} " } 
chain.rescue { |reason| puts "Failure: #{reason}" } 

chain.execute 
sleep(2) 

それをuts:

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
20 
60 
Success: 60