#759: add state_machine into the ProductBuildList

This commit is contained in:
Vokhmin Alexey V 2012-12-06 23:18:28 +04:00
parent e3e228de33
commit eae2b2ce02
5 changed files with 76 additions and 23 deletions

View File

@ -26,9 +26,12 @@ class Platforms::ProductBuildListsController < Platforms::BaseController
end end
def cancel def cancel
@product_build_list.cancel_job if @product_build_list.cancel
flash[:notice] = t('layout.build_lists.will_be_canceled') notice = t('layout.build_lists.will_be_canceled')
redirect_to platform_product_product_build_list_path(@platform, @product, @product_build_list) else
notice = t('layout.build_lists.cancel_fail')
end
redirect_to :back, :notice => notice
end end
def log def log

View File

@ -142,7 +142,7 @@ class BuildList < ActiveRecord::Base
after_transition :on => :published, :do => [:set_version_and_tag, :actualize_packages] after_transition :on => :published, :do => [:set_version_and_tag, :actualize_packages]
after_transition :on => :cancel, :do => [:cancel_job], after_transition :on => :cancel, :do => [:cancel_job],
:if => lambda { |build_list| build_list.build_canceling? } :if => lambda { |build_list| build_list.new_core? }
after_transition :on => [:published, :fail_publish, :build_error], :do => :notify_users after_transition :on => [:published, :fail_publish, :build_error], :do => :notify_users
after_transition :on => :build_success, :do => :notify_users, after_transition :on => :build_success, :do => :notify_users,
@ -178,12 +178,12 @@ class BuildList < ActiveRecord::Base
!build_list.new_core? && build_list.can_cancel? && BuildServer.delete_build_list(build_list.bs_id) == BuildServer::SUCCESS !build_list.new_core? && build_list.can_cancel? && BuildServer.delete_build_list(build_list.bs_id) == BuildServer::SUCCESS
} }
transition [:build_pending, :build_started] => :build_canceling, :if => lambda { |build_list| transition [:build_pending, :build_started] => :build_canceling, :if => lambda { |build_list|
build_list.new_core? && build_list.can_cancel? build_list.new_core?
} }
end end
event :build_canceled do event :build_canceled do
transition [:build_canceling] => :build_canceled, :if => lambda { |build_list| transition :build_canceling => :build_canceled, :if => lambda { |build_list|
build_list.new_core? build_list.new_core?
} }
end end

View File

@ -10,13 +10,15 @@ class ProductBuildList < ActiveRecord::Base
BUILD_STARTED = 3 BUILD_STARTED = 3
BUILD_CANCELED = 4 BUILD_CANCELED = 4
BUILD_CANCELING = 5 BUILD_CANCELING = 5
WAITING_FOR_RESPONSE = 4000
STATUSES = [ BUILD_STARTED, STATUSES = [ BUILD_STARTED,
BUILD_COMPLETED, BUILD_COMPLETED,
BUILD_FAILED, BUILD_FAILED,
BUILD_PENDING, BUILD_PENDING,
BUILD_CANCELED, BUILD_CANCELED,
BUILD_CANCELING BUILD_CANCELING,
WAITING_FOR_RESPONSE
] ]
HUMAN_STATUSES = { BUILD_STARTED => :build_started, HUMAN_STATUSES = { BUILD_STARTED => :build_started,
@ -24,7 +26,8 @@ class ProductBuildList < ActiveRecord::Base
BUILD_FAILED => :build_failed, BUILD_FAILED => :build_failed,
BUILD_PENDING => :build_pending, BUILD_PENDING => :build_pending,
BUILD_CANCELED => :build_canceled, BUILD_CANCELED => :build_canceled,
BUILD_CANCELING => :build_canceling BUILD_CANCELING => :build_canceling,
WAITING_FOR_RESPONSE => :waiting_for_response
} }
belongs_to :product belongs_to :product
@ -61,10 +64,44 @@ class ProductBuildList < ActiveRecord::Base
scope :scoped_to_product_name, lambda {|product_name| joins(:product).where('products.name LIKE ?', "%#{product_name}%")} scope :scoped_to_product_name, lambda {|product_name| joins(:product).where('products.name LIKE ?', "%#{product_name}%")}
scope :recent, order("#{table_name}.updated_at DESC") scope :recent, order("#{table_name}.updated_at DESC")
after_create :add_job_to_abf_worker_queue after_create :place_build
before_destroy :can_destroy? before_destroy :can_destroy?
after_destroy :xml_delete_iso_container after_destroy :xml_delete_iso_container
state_machine :status, :initial => :waiting_for_response do
event :place_build do
transition :waiting_for_response => :build_pending, :if => lambda { |pbl|
pbl.add_job_to_abf_worker_queue
}
end
event :start_build do
transition :build_pending => :build_started
end
event :cancel do
transition [:build_pending, :build_started] => :build_canceling
end
after_transition :on => :cancel, :do => [:cancel_job]
event :build_canceled do
transition :build_canceling => :build_canceled
end
event :build_success do
transition :build_started => :build_completed
end
event :build_error do
transition [:build_started, :build_canceled, :build_canceling] => :build_failed
end
HUMAN_STATUSES.each do |code,name|
state name, :value => code
end
end
def build_started? def build_started?
status == BUILD_STARTED status == BUILD_STARTED
end end

View File

@ -1,14 +1,30 @@
module AbfWorker module AbfWorker
class IsoWorkerObserver class IsoWorkerObserver
BUILD_COMPLETED = 0
BUILD_FAILED = 1
BUILD_PENDING = 2
BUILD_STARTED = 3
BUILD_CANCELED = 4
@queue = :iso_worker_observer @queue = :iso_worker_observer
def self.perform(options) def self.perform(options)
status = options['status'].to_i status = options['status'].to_i
pbl = ProductBuildList.find options['id'] pbl = ProductBuildList.find options['id']
pbl.status = status case status
pbl.results = options['results'] if status != ProductBuildList::BUILD_STARTED when BUILD_COMPLETED
pbl.build_success
when BUILD_FAILED
pbl.build_error
when BUILD_STARTED
pbl.start_build
when BUILD_CANCELED
pbl.build_canceled
end
if status != BUILD_STARTED
pbl.results = options['results']
pbl.save! pbl.save!
end end
end
end end
end end

View File

@ -1,9 +1,8 @@
module AbfWorker module AbfWorker
module ModelHelper module ModelHelper
# In model which contains this helper should be: # In model which contains this helper should be:
# - BUILD_CANCELING
# - BUILD_CANCELED
# - #abf_worker_args # - #abf_worker_args
# - #build_canceled
def abf_worker_log def abf_worker_log
q = 'abfworker::' q = 'abfworker::'
@ -22,15 +21,13 @@ module AbfWorker
end end
def cancel_job def cancel_job
update_attributes({:status => self.class::BUILD_CANCELING})
deleted = Resque::Job.destroy( deleted = Resque::Job.destroy(
worker_queue, worker_queue,
worker_queue_class, worker_queue_class,
abf_worker_args abf_worker_args
) )
if deleted == 1 if deleted == 1
update_attributes({:status => self.class::BUILD_CANCELED}) build_canceled
else else
send_stop_signal send_stop_signal
end end