按顺序运行Rails作业

时间:2017-12-22 19:36:43

标签: ruby-on-rails jobs

我有三个Rails工作来处理足球锦标赛中的球员黄牌/红牌,以及这些球员因获得这张牌而受到的惩罚。
我们的想法是,第一份工作收集所有发生率(发生率是指玩家获得黄牌,举例),并计算所有玩家获得的牌。

class ProcessBookedPlayersJob < ApplicationJob
  queue_as :default
  @cards = []

  def perform(*args)
    @cards = []
    yellows = calculate_cards(1)
    reds = calculate_cards(2)
    @cards << yellows << reds
  end

  def after_perform(*match)
    #ProcessPenaltiesJob.perform_later @cards
    ProcessPenalties.perform_later @cards
    #PenaltiesFinalizerJob.perform_later match
    PenaltiesFinalizer.perform_later match
  end

  def calculate_cards(card_type)
    cards = Hash.new
    players = Player.fetch_players_with_active_incidences
    players.each { |p|
      # 1 is yellow, 2 is red
      counted_cards = Incidence.incidences_for_player_id_and_incidence_type(p.id, card_type).size
      cards[p] = counted_cards
    }
    return cards
  end
end

创建实例时执行第一个作业。

class Incidence < ApplicationRecord
  belongs_to :player
  belongs_to :match

  after_save :process_incidences, on: :create

  def self.incidences_for_player_id_and_incidence_type(player_id, card_type)
    return Incidence.where(status: 1).where(incidence_type: card_type).where(player_id: player_id)
  end

  protected
  def process_incidences
    ProcessBookedPlayers.perform_later
  end
end

在此之后,另一个作业运行并根据上一个作业创建的哈希输出创建必要的惩罚(例如,惩罚是对下一场比赛的禁令)。

class ProcessPenaltiesJob < ApplicationJob
  queue_as :default

  def perform(*cards)
    yellows = cards[0]
    reds = cards[1]
    create_penalties_for_yellow_cards(yellows)
    create_penalties_for_red_cards(reds)
  end

  # rest of the job...

此外还有另一项工作,即在这些禁令过期后将其设置为禁用。

class PenaltiesFinalizerJob < ApplicationJob
  queue_as :default

  def perform(match)
    active_penalties = Penalty.find_by(status: 1)
    active_penalties.each do |p|
      #penalty.starting_match.order + penalty.length == el_match_que_inserte.order (ver si seria >=)
      if p.match.order + p.length >= match.order
        p.status = 2    # Inactivate
        p.save!
      end
    end
  end
end

正如您在ProcessBookedPlayersJob的{​​{1}}方法

中所看到的那样
after_perform

我正试图让这两个其他工作被执行(def after_perform(*match) ProcessPenalties.perform_later @cards PenaltiesFinalizer.perform_later match end ProcessPenaltiesJob)没有运气。正在执行作业PenaltiesFinalizerJob(因为我可以在日志中看到这一点)

ProcessBookedPlayersJob

但是其他两个工作没有被执行。那么,在[ActiveJob] [ProcessBookedPlayersJob] [dbb8445e-a706-4443-9cb8-2c45f49a4f8f] Performed ProcessBookedPlayersJob (Job ID: dbb8445e-a706-4443-9cb8-2c45f49a4f8f) from Async(default) in 38.81ms 完成执行后,如何同时运行ProcessPenaltiesJobPenaltiesFinalizerJob?我不介意它们是否并行运行,但它们需要在第一个完成后运行,因为它们需要输出作为输入。

我搜索了这个,我找到的最接近的匹配是this answer。引用它:

  

但是,如果您正在谈论的顺序作业有所不同   工作/班级,然后你可以在第一份工作后调用另一份工作   已经结束了。

那是完全我想要的行为......但我怎样才能让我的工作按顺序运行?
现在,我正在考虑将第一个作业的逻辑添加到ProcessBookedPlayersJob的{​​{1}}钩子中,但这听起来不太自然。有没有其他方法来管理我的工作执行?
非常感谢提前

0 个答案:

没有答案