Module: OscMacheteRails::Statusable
- Defined in:
- lib/osc_machete_rails/statusable.rb
Overview
Methods that deal with pbs batch job status management within a Rails ActiveRecord model
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
- .classes ⇒ Object
- .included(obj) ⇒ Object
-
.update_status_of_all_active_jobs ⇒ Object
for each Statusable, call update_status! on active jobs.
Instance Method Summary collapse
-
#job ⇒ Object
Returns associated OSC::Machete::Job instance.
-
#job=(new_job) ⇒ Object
Setter that accepts an OSC::Machete::Job instance.
-
#results_valid? ⇒ Boolean
A hook that can be overidden with custom code also looks for default validation methods for existing WARNING: THIS USES ActiveSupport::Inflector methods underscore and parameterize.
-
#results_validation_method_name ⇒ String
Build the results validation method name from script_name attr using ActiveSupport methods.
-
#status ⇒ Object
getter returns a Status value from CHAR or a Status value.
- #status=(s) ⇒ Object
-
#stop(update: true) ⇒ Object
delete the batch job and update status may raise PBS::Error as it is unhandled here!.
-
#update_status!(force: false) ⇒ Object
FIXME: should have a unit test for this! job.update_status! will update and save object if submitted? and ! completed? and status changed from previous state force will cause status to update regardless of completion status, redoing the validations.
Class Method Details
.classes ⇒ Object
63 64 65 |
# File 'lib/osc_machete_rails/statusable.rb', line 63 def self.classes @classes ||= [] end |
.included(obj) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/osc_machete_rails/statusable.rb', line 27 def self.included(obj) # track the classes that include this module self.classes << Kernel.const_get(obj.name) unless obj.name.nil? # add class methods obj.send(:extend, ClassMethods) begin obj.class_eval do # Store job object info in a JSON column and replace old column methods if respond_to?(:table_exists?) && table_exists? && respond_to?(:column_names) && column_names.include?('job_cache') store :job_cache, accessors: [ :script, :pbsid, :host ], coder: JSON delegate :script_name, to: :job define_method :job_path do job.path end else define_method(:job_cache) do { script: (job_path && script_name) ? Pathname.new(job_path).join(script_name) : nil, pbsid: pbsid, host: nil } end end end rescue StandardError => e msg = "\nIf you are precompiling assets, you can ignore this:\n\tError thrown: #{e.inspect}" msg += "\n\tError thrown in OscMacheteRails::Statusable.included when trying to add job_cache to the class including Statusable: #{obj.name}." msg += "\n\tjob_cache method was not added to class." unless obj.method_defined? :job_cache msg += "\n\n" STDERR.puts msg end end |
.update_status_of_all_active_jobs ⇒ Object
for each Statusable, call update_status! on active jobs
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/osc_machete_rails/statusable.rb', line 68 def self.update_status_of_all_active_jobs # to eager load classes, set config.eager_load to true or execute Rails.application.eager_load! if self.classes.empty? Rails.logger.warn "Statusable.classes Array is empty. This should contain a list of all the classes that include Statusable. " \ "This could occur if the Rails app is not configured to eager load classes." else Rails.logger.debug "Updating active job statuses via Statusable.update_status_of_all_active_jobs." end self.classes.each do |klass| klass.active.to_a.each(&:update_status!) if klass.respond_to?(:active) end end |
Instance Method Details
#job ⇒ Object
Returns associated OSC::Machete::Job instance
123 124 125 |
# File 'lib/osc_machete_rails/statusable.rb', line 123 def job OSC::Machete::Job.new(job_cache.symbolize_keys) end |
#job=(new_job) ⇒ Object
Setter that accepts an OSC::Machete::Job instance
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/osc_machete_rails/statusable.rb', line 99 def job=(new_job) if self.has_attribute?(:job_cache) self.script = new_job.script_path.to_s self.pbsid = new_job.pbsid self.host = new_job.host if new_job.respond_to?(:host) else self.script_name = new_job.script_name self.job_path = new_job.path.to_s self.pbsid = new_job.pbsid end begin self.status = new_job.status rescue PBS::Error => e # a safe default self.status = OSC::Machete::Status.queued # log the error Rails.logger.error("After submitting the job with pbsid: #{pbsid}," \ " checking the status raised a PBS::Error: #{e.}") end end |
#results_valid? ⇒ Boolean
A hook that can be overidden with custom code also looks for default validation methods for existing WARNING: THIS USES ActiveSupport::Inflector methods underscore and parameterize
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/osc_machete_rails/statusable.rb', line 144 def results_valid? valid = true if self.respond_to?(:script_name) && !script_name.nil? if self.respond_to?(results_validation_method_name) valid = self.send(results_validation_method_name) end end valid end |
#results_validation_method_name ⇒ String
Build the results validation method name from script_name attr using ActiveSupport methods
Call this using the Rails console to see what method you should implement to support results validation for that job.
using ActiveSupport methods
135 136 137 |
# File 'lib/osc_machete_rails/statusable.rb', line 135 def results_validation_method_name File.basename(script_name, ".*").underscore.parameterize(separator: '_') + "_results_valid?" end |
#status ⇒ Object
getter returns a Status value from CHAR or a Status value
14 15 16 |
# File 'lib/osc_machete_rails/statusable.rb', line 14 def status OSC::Machete::Status.new(super) end |
#status=(s) ⇒ Object
9 10 11 |
# File 'lib/osc_machete_rails/statusable.rb', line 9 def status=(s) super(OSC::Machete::Status.new(s).char) end |
#stop(update: true) ⇒ Object
delete the batch job and update status may raise PBS::Error as it is unhandled here!
20 21 22 23 24 25 |
# File 'lib/osc_machete_rails/statusable.rb', line 20 def stop(update: true) return unless status.active? job.delete update(status: OSC::Machete::Status.failed) if update end |
#update_status!(force: false) ⇒ Object
FIXME: should have a unit test for this! job.update_status! will update and save object if submitted? and ! completed? and status changed from previous state force will cause status to update regardless of completion status, redoing the validations. This way, if you are fixing validation methods you can use the Rails console to update the status of a Workflow by doing this:
Container.last.jobs.each {|j| j.update_status!(force: true) }
Or for a single statusable such as job:
job.update_status!(force: true)
FIXME: should log whether a validation method was called or throw a warning that no validation method was found (the one that would have been called)
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/osc_machete_rails/statusable.rb', line 173 def update_status!(force: false) # this will make it easier to differentiate from current_status cached_status = status # by default only update if its an active job if (cached_status.not_submitted? && pbsid) || cached_status.active? || force # get the current status from the system current_status = job.status # if job is done, lets re-validate if current_status.completed? current_status = results_valid? ? OSC::Machete::Status.passed : OSC::Machete::Status.failed end if (current_status != cached_status) || force self.status = current_status self.save end end rescue PBS::Error => e # we log the error but we just don't update the status Rails.logger.error("During update_status! call on job with pbsid #{pbsid} and id #{id}" \ " a PBS::Error was thrown: #{e.}") end |