module TavernaPlayer::Concerns::Models::Run

Constants

STATES

Public Instance Methods

cancel() click to toggle source

There are two courses of action here:

  • If the run is already running then cancel this run by setting the stop flag. This is done to allow the delayed job that is monitoring the run to delete it and clean up Taverna Server gracefully.

  • If the run is still in the queue, destroy the queue object. This is checked in a transaction so that we don't get hit with a race condition between checking the queued status of the run and actually removing it from the queue.

In both cases the stop flag is set to mark the run as cancelled internally.

See the note above about the :cancelled state.

# File lib/taverna_player/concerns/models/run.rb, line 147
def cancel
  return unless incomplete?

  # Set the stop flag for all cases.
  self.stop = true

  # If the run has a delayed job and it hasn't been locked yet, or it
  # has failed, then we just remove it from the queue directly and
  # mark the run as cancelled.
  unless delayed_job.nil?
    delayed_job.with_lock do
      if delayed_job.locked_by.nil? || !delayed_job.failed_at.nil?
        delayed_job.destroy
        self.state = :cancelled
        self.status_message_key = "cancelled"
      end
    end
  end

  save
end
cancelled?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 211
def cancelled?
  state == :cancelled
end
cancelling?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 215
def cancelling?
  state == :cancelling
end
complete?() click to toggle source

This is used as a catch-all for finished, cancelled, failed, job_failed? and timeout

# File lib/taverna_player/concerns/models/run.rb, line 238
def complete?
  finished? || cancelled? || failed? || job_failed? || timeout?
end
destroy_failed_delayed_jobs() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 120
def destroy_failed_delayed_jobs
  delayed_job.destroy unless delayed_job.nil?
end
enqueue() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 111
def enqueue
  worker = TavernaPlayer::Worker.new(self)
  job = Delayed::Job.enqueue worker, :queue => TavernaPlayer.job_queue_name

  self.delayed_job = job
  self.status_message_key = "pending"
  save
end
failed?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 223
def failed?
  state == :failed
end
finished?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 207
def finished?
  state == :finished
end
has_parent?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 242
def has_parent?
  !parent_id.nil?
end
incomplete?() click to toggle source

This is used as a catch-all for pending?, initialized? and running?

# File lib/taverna_player/concerns/models/run.rb, line 232
def incomplete?
  running? || pending? || initialized?
end
initialize_child_run() click to toggle source

A child run MUST have the same workflow as its parent.

# File lib/taverna_player/concerns/models/run.rb, line 93
def initialize_child_run
  self.workflow = parent.workflow
end
initialized?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 199
def initialized?
  state == :initialized
end
job_failed?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 227
def job_failed?
  !delayed_job.nil? && !delayed_job.failed_at.nil?
end
pending?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 195
def pending?
  state == :pending
end
populate_child_inputs() click to toggle source

For each input on the parent run, make sure we have an equivalent on the child. Copy the values/files of inputs that are missing.

# File lib/taverna_player/concerns/models/run.rb, line 99
def populate_child_inputs
  parent.inputs.each do |i|
    input = TavernaPlayer::RunPort::Input.find_or_initialize_by_run_id_and_name(id, i.name)
    if input.new_record?
      input.value = i.value
      input.file = i.file
      input.depth = i.depth
      input.save
    end
  end
end
root_ancestor() click to toggle source

Get the original ancestor of this run. In practice this is the first run in the chain without a parent.

# File lib/taverna_player/concerns/models/run.rb, line 128
def root_ancestor
  has_parent? ? parent.root_ancestor : self
end
running?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 203
def running?
  state == :running
end
state() click to toggle source

Return state as a symbol. If a run is running, but has been asked to stop, then it is :cancelling. This is a pseudo-state to avoid race conditions when cancelling a run so is specifically NOT in the list of allowed states above.

# File lib/taverna_player/concerns/models/run.rb, line 173
def state
  s = self[:saved_state].to_sym
  if s == :running
    stop ? :cancelling : :running
  else
    s
  end
end
state=(state) click to toggle source

Save state as a downcased string. See the note above about why a state cannot be used to actually cancel a run.

# File lib/taverna_player/concerns/models/run.rb, line 184
def state=(state)
  s = state.to_s.downcase
  return if s == "cancelled" && !stop
  self[:saved_state] = s
end
status_message() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 190
def status_message
  key = status_message_key.nil? ? saved_state : status_message_key
  I18n.t("taverna_player.status.#{key}")
end
timeout?() click to toggle source
# File lib/taverna_player/concerns/models/run.rb, line 219
def timeout?
  state == :timeout
end