我已经集成了延迟作业以从后台运行 Jenkins 构建。因此,对于每个构建,我都使用 gem 来更新我的状态AASM
。每次构建完成后,我都会从延迟的工作中收到错误"Event 'success' cannot transition from 'success'
因为为什么会发生,我无法找到。
我从我的approver_controller.rb
打电话给我的工作
@build_request.delay(attempts: 1).run_batch
build_request模型中,我有我的作业方法来执行 Jenkins 批处理
class BuildRequest < ApplicationRecord
include AASM
aasm :column => :build_state do
state :pending, initial: true
state :onhold
state :release
state :approved
state :rejected
state :success
state :failed
event :approve do
transitions from: [:pending], to: :approved
end
event :onhold do
transitions from: [:pending], to: :onhold
end
event :release do
transitions from: [:onhold], to: :pending
end
event :reject do
transitions from: [:pending], to: :rejected
end
event :success do
transitions from: [:approved], to: :success
end
event :fail do
transitions from: [:approved], to: :failed
end
end
def run_batch
if self.approved?
file_name = "#{self.project_job_name}_#{self.id}.txt"
new_file = File.open(file_name, "w+")
new_file.puts self.project.job_name + "r"
new_file.puts input_path(self)
new_file.close
FileUtils.mv(Rails.root.join(file_name), Rails.root.join('public'))
Net::SCP.start(ENV["IP_ADDRESSS"], ENV["USER_NAME"], :password => ENV["PASSWORD"]) do |scp|
# asynchronous upload; call returns immediately and requires SSH
# event loop to run
channel = scp.upload(Rails.root.join('public', file_name).to_s, jenkins_build_path)
channel.wait
end
Net::SSH.start(ENV["IP_ADDRESSS"], ENV["USER_NAME"], :password => ENV["PASSWORD"]) do |ssh|
output = ssh.exec!("file_path" " file_name")
# start building job
build_status = ApplicationController.helpers.jenkins_client.job.build(self.project_job_name)
build_status == "201" ? self.success : self.failed
end
end
end
我遇到了同样的问题,我花了一些时间才弄清楚:
DelayedJob 会自动向模型添加success
方法,并在作业完成后运行该方法。这可能会与您使用 AASM 执行的状态管理冲突,导致它(例如(处于成功状态(通过您的代码(,然后让延迟作业无意中尝试再次将其转换为成功状态。