我有三个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
完成执行后,如何同时运行ProcessPenaltiesJob
和PenaltiesFinalizerJob
?我不介意它们是否并行运行,但它们需要在第一个完成后运行,因为它们需要输出作为输入。
我搜索了这个,我找到的最接近的匹配是this answer。引用它:
但是,如果您正在谈论的顺序作业有所不同 工作/班级,然后你可以在第一份工作后调用另一份工作 已经结束了。
那是完全我想要的行为......但我怎样才能让我的工作按顺序运行?
现在,我正在考虑将第一个作业的逻辑添加到ProcessBookedPlayersJob
的{{1}}钩子中,但这听起来不太自然。有没有其他方法来管理我的工作执行?
非常感谢提前