昨日の続き。
この書き方ならパフォーマンスにも問題無さそうだしネストしたタスクも綺麗に書けて良さそう。
require 'rubygems' require 'eventmachine' MAX_RETRY_COUNT = 3 CONCURRENCY = 2 class Mailer < EM::DefaultDeferrable def initialize(mail_address) @mail_address = mail_address callback { puts "#{@mail_address}: sent" } errback { puts "#{@mail_address}: failed" } end def send puts "#{@mail_address}: sending..." rand >= 0.5 ? succeed : fail end end jobs = (1..5).to_a running = false retry_count = 0 EM.run { EM.add_periodic_timer(1) { break if running puts "retry (#{retry_count}/#{MAX_RETRY_COUNT})" if retry_count > 0 EM::Iterator.new(jobs.clone, CONCURRENCY).each( proc{|i, iter| mailer = Mailer.new("hoge_#{i}@example.com") mailer.callback { mailer2 = Mailer.new("fuga_#{i}@example.com") mailer2.callback { jobs.delete(i) iter.next } mailer2.errback { iter.next } mailer2.send } mailer.errback { iter.next } mailer.send }, proc{ if jobs.length > 0 and retry_count < MAX_RETRY_COUNT retry_count += 1 running = false else puts 'done!' EM.stop end }) running = true } }