accept_attribute_as_json :script_parameters, Hash
accept_attribute_as_json :runtime_constraints, Hash
accept_attribute_as_json :tasks_summary, Hash
- skip_before_filter :find_object_by_uuid, :only => :queue
- skip_before_filter :render_404_if_no_object, :only => :queue
+ skip_before_filter :find_object_by_uuid, :only => [:queue, :queue_size]
+ skip_before_filter :render_404_if_no_object, :only => [:queue, :queue_size]
def create
[:repository, :script, :script_version, :script_parameters].each do |r|
["script_version", "in git",
params[:minimum_script_version] || resource_attrs[:script_version]],
["script_version", "not in git", params[:exclude_script_versions]],
- ].reject { |filter| filter.last.nil? }
+ ].reject { |filter| filter.last.nil? or filter.last.empty? }
if image_search = resource_attrs[:runtime_constraints].andand["docker_image"]
if image_tag = resource_attrs[:runtime_constraints]["docker_image_tag"]
image_search += ":#{image_tag}"
else
@filters.append(["docker_image_locator", "=", nil])
end
+ if sdk_version = resource_attrs[:runtime_constraints].andand["arvados_sdk_version"]
+ @filters.append(["arvados_sdk_version", "in git", sdk_version])
+ end
begin
load_job_specific_filters
rescue ArgumentError => error
incomplete_job = nil
@objects.each do |j|
if j.nondeterministic != true and
- ((j.success == true and j.output != nil) or j.running == true) and
+ ["Queued", "Running", "Complete"].include?(j.state) and
j.script_parameters == resource_attrs[:script_parameters]
- if j.running && j.owner_uuid == current_user.uuid
+ if j.state != "Complete" && j.owner_uuid == current_user.uuid
# We'll use this if we don't find a job that has completed
incomplete_job ||= j
else
- if Collection.readable_by(current_user).find_by_uuid(j.output)
+ if Collection.readable_by(current_user).find_by_portable_data_hash(j.output)
# Record the first job in the list
if !@object
@object = j
def cancel
reload_object_before_update
- @object.update_attributes! cancelled_at: Time.now
+ @object.update_attributes! state: Job::Cancelled
+ show
+ end
+
+ def lock
+ @object.lock current_user.uuid
show
end
params[:order] ||= ['priority desc', 'created_at']
load_limit_offset_order_params
load_where_param
- @where.merge!({
- started_at: nil,
- is_locked_by_uuid: nil,
- cancelled_at: nil,
- success: nil
- })
+ @where.merge!({state: Job::Queued})
return if false.equal?(load_filters_param)
find_objects_for_index
index
end
+ def queue_size
+ # Users may not be allowed to see all the jobs in the queue, so provide a
+ # method to get just the queue size in order to get a gist of how busy the
+ # cluster is.
+ render :json => {:queue_size => Job.queue.size}
+ end
+
def self._create_requires_parameters
(super rescue {}).
merge({
def load_job_specific_filters
# Convert Job-specific @filters entries into general SQL filters.
script_info = {"repository" => nil, "script" => nil}
- script_range = {"exclude_versions" => []}
- @filters.select! do |filter|
- if (script_info.has_key? filter[0]) and (filter[1] == "=")
- if script_info[filter[0]].nil?
- script_info[filter[0]] = filter[2]
- elsif script_info[filter[0]] != filter[2]
- raise ArgumentError.new("incompatible #{filter[0]} filters")
+ git_filters = Hash.new do |hash, key|
+ hash[key] = {"max_version" => "HEAD", "exclude_versions" => []}
+ end
+ @filters.select! do |(attr, operator, operand)|
+ if (script_info.has_key? attr) and (operator == "=")
+ if script_info[attr].nil?
+ script_info[attr] = operand
+ elsif script_info[attr] != operand
+ raise ArgumentError.new("incompatible #{attr} filters")
end
end
- case filter[0..1]
- when ["script_version", "in git"]
- script_range["min_version"] = filter.last
+ case operator
+ when "in git"
+ git_filters[attr]["min_version"] = operand
false
- when ["script_version", "not in git"]
- begin
- script_range["exclude_versions"] += filter.last
- rescue TypeError
- script_range["exclude_versions"] << filter.last
- end
+ when "not in git"
+ git_filters[attr]["exclude_versions"] += Array.wrap(operand)
false
- when ["docker_image_locator", "in docker"], ["docker_image_locator", "not in docker"]
- filter[1].sub!(/ docker$/, '')
- search_list = filter[2].is_a?(Enumerable) ? filter[2] : [filter[2]]
- filter[2] = search_list.flat_map do |search_term|
+ when "in docker", "not in docker"
+ image_hashes = Array.wrap(operand).flat_map do |search_term|
image_search, image_tag = search_term.split(':', 2)
- Collection.uuids_for_docker_image(image_search, image_tag, @read_users)
+ Collection.
+ find_all_for_docker_image(image_search, image_tag, @read_users).
+ map(&:portable_data_hash)
end
- true
+ @filters << [attr, operator.sub(/ docker$/, ""), image_hashes]
+ false
else
true
end
end
# Build a real script_version filter from any "not? in git" filters.
- if (script_range.size > 1) or script_range["exclude_versions"].any?
- script_info.each_pair do |key, value|
- if value.nil?
- raise ArgumentError.new("script_version filter needs #{key} filter")
+ git_filters.each_pair do |attr, filter|
+ case attr
+ when "script_version"
+ script_info.each_pair do |key, value|
+ if value.nil?
+ raise ArgumentError.new("script_version filter needs #{key} filter")
+ end
end
+ filter["repository"] = script_info["repository"]
+ begin
+ filter["max_version"] = resource_attrs[:script_version]
+ rescue
+ # Using HEAD, set earlier by the hash default, is fine.
+ end
+ when "arvados_sdk_version"
+ filter["repository"] = "arvados"
+ else
+ raise ArgumentError.new("unknown attribute for git filter: #{attr}")
end
- last_version = begin resource_attrs[:script_version] rescue "HEAD" end
version_range = Commit.find_commit_range(current_user,
- script_info["repository"],
- script_range["min_version"],
- last_version,
- script_range["exclude_versions"])
+ filter["repository"],
+ filter["min_version"],
+ filter["max_version"],
+ filter["exclude_versions"])
if version_range.nil?
raise ArgumentError.
- new(["error searching #{script_info['repository']} from",
- "#{script_range['min_version']} to #{last_version},",
- "excluding #{script_range['exclude_versions']}"].join(" "))
+ new("error searching #{filter['repository']} from " +
+ "'#{filter['min_version']}' to '#{filter['max_version']}', " +
+ "excluding #{filter['exclude_versions']}")
end
- @filters.append(["script_version", "in", version_range])
+ @filters.append([attr, "in", version_range])
end
end