From eae2b2ce02ea6d54baceb2571c56e1fd4ba4cbc3 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Thu, 6 Dec 2012 23:18:28 +0400 Subject: [PATCH] #759: add state_machine into the ProductBuildList --- .../product_build_lists_controller.rb | 9 ++- app/models/build_list.rb | 6 +- app/models/product_build_list.rb | 55 ++++++++++++++++--- lib/abf_worker/iso_worker_observer.rb | 22 +++++++- lib/abf_worker/model_helper.rb | 7 +-- 5 files changed, 76 insertions(+), 23 deletions(-) diff --git a/app/controllers/platforms/product_build_lists_controller.rb b/app/controllers/platforms/product_build_lists_controller.rb index 2bc8e4bbd..c41dce55d 100644 --- a/app/controllers/platforms/product_build_lists_controller.rb +++ b/app/controllers/platforms/product_build_lists_controller.rb @@ -26,9 +26,12 @@ class Platforms::ProductBuildListsController < Platforms::BaseController end def cancel - @product_build_list.cancel_job - flash[:notice] = t('layout.build_lists.will_be_canceled') - redirect_to platform_product_product_build_list_path(@platform, @product, @product_build_list) + if @product_build_list.cancel + notice = t('layout.build_lists.will_be_canceled') + else + notice = t('layout.build_lists.cancel_fail') + end + redirect_to :back, :notice => notice end def log diff --git a/app/models/build_list.rb b/app/models/build_list.rb index d381a5894..de5fcff6e 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -142,7 +142,7 @@ class BuildList < ActiveRecord::Base after_transition :on => :published, :do => [:set_version_and_tag, :actualize_packages] 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 => :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 } transition [:build_pending, :build_started] => :build_canceling, :if => lambda { |build_list| - build_list.new_core? && build_list.can_cancel? + build_list.new_core? } end 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? } end diff --git a/app/models/product_build_list.rb b/app/models/product_build_list.rb index 501e058a3..d7a1777f3 100644 --- a/app/models/product_build_list.rb +++ b/app/models/product_build_list.rb @@ -4,19 +4,21 @@ class ProductBuildList < ActiveRecord::Base include AbfWorker::ModelHelper delegate :url_helpers, to: 'Rails.application.routes' - BUILD_COMPLETED = 0 - BUILD_FAILED = 1 - BUILD_PENDING = 2 - BUILD_STARTED = 3 - BUILD_CANCELED = 4 - BUILD_CANCELING = 5 + BUILD_COMPLETED = 0 + BUILD_FAILED = 1 + BUILD_PENDING = 2 + BUILD_STARTED = 3 + BUILD_CANCELED = 4 + BUILD_CANCELING = 5 + WAITING_FOR_RESPONSE = 4000 STATUSES = [ BUILD_STARTED, BUILD_COMPLETED, BUILD_FAILED, BUILD_PENDING, BUILD_CANCELED, - BUILD_CANCELING + BUILD_CANCELING, + WAITING_FOR_RESPONSE ] HUMAN_STATUSES = { BUILD_STARTED => :build_started, @@ -24,7 +26,8 @@ class ProductBuildList < ActiveRecord::Base BUILD_FAILED => :build_failed, BUILD_PENDING => :build_pending, BUILD_CANCELED => :build_canceled, - BUILD_CANCELING => :build_canceling + BUILD_CANCELING => :build_canceling, + WAITING_FOR_RESPONSE => :waiting_for_response } 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 :recent, order("#{table_name}.updated_at DESC") - after_create :add_job_to_abf_worker_queue + after_create :place_build before_destroy :can_destroy? 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? status == BUILD_STARTED end diff --git a/lib/abf_worker/iso_worker_observer.rb b/lib/abf_worker/iso_worker_observer.rb index 026874368..4bac9f6d7 100644 --- a/lib/abf_worker/iso_worker_observer.rb +++ b/lib/abf_worker/iso_worker_observer.rb @@ -1,13 +1,29 @@ module AbfWorker class IsoWorkerObserver + BUILD_COMPLETED = 0 + BUILD_FAILED = 1 + BUILD_PENDING = 2 + BUILD_STARTED = 3 + BUILD_CANCELED = 4 @queue = :iso_worker_observer def self.perform(options) status = options['status'].to_i pbl = ProductBuildList.find options['id'] - pbl.status = status - pbl.results = options['results'] if status != ProductBuildList::BUILD_STARTED - pbl.save! + case status + 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! + end end end diff --git a/lib/abf_worker/model_helper.rb b/lib/abf_worker/model_helper.rb index 0803ead49..b9a921ff6 100644 --- a/lib/abf_worker/model_helper.rb +++ b/lib/abf_worker/model_helper.rb @@ -1,9 +1,8 @@ module AbfWorker module ModelHelper # In model which contains this helper should be: - # - BUILD_CANCELING - # - BUILD_CANCELED # - #abf_worker_args + # - #build_canceled def abf_worker_log q = 'abfworker::' @@ -22,15 +21,13 @@ module AbfWorker end def cancel_job - update_attributes({:status => self.class::BUILD_CANCELING}) - deleted = Resque::Job.destroy( worker_queue, worker_queue_class, abf_worker_args ) if deleted == 1 - update_attributes({:status => self.class::BUILD_CANCELED}) + build_canceled else send_stop_signal end