[ARVADOS] created: 2e86954da9d4561cc42d52e8505eb12aa95f6470

git at public.curoverse.com git at public.curoverse.com
Sat Apr 12 21:01:27 EDT 2014


        at  2e86954da9d4561cc42d52e8505eb12aa95f6470 (commit)


commit 2e86954da9d4561cc42d52e8505eb12aa95f6470
Author: Tom Clegg <tom at curoverse.com>
Date:   Sat Apr 12 20:57:28 2014 -0400

    Make arrays non-editable on pipeline instance page.
    
    (This is better than offering to edit them but mangling them in the
    process.)

diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb
index 5bae53d..e25bb57 100644
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@ -156,8 +156,8 @@ module ApplicationHelper
     elsif dataclass == 'number'
       datatype = 'number'
     elsif attrvalue.is_a? Array
-      datatype = 'text'
-      attrvalue = attrvalue.to_s
+      # TODO: find a way to edit arrays with x-editable
+      return attrvalue
     elsif attrvalue.is_a? Fixnum or attrvalue.is_a? Float
       datatype = 'number'
     elsif attrvalue.is_a? String

commit 10b0009bb8d4a5bf30f521f2e7fac6e69dd09a68
Author: Tom Clegg <tom at curoverse.com>
Date:   Sat Apr 12 20:50:23 2014 -0400

    Do not reuse cancelled jobs. Do not consider nil outputs from
    incomplete jobs when deciding whether a script is deterministic.

diff --git a/services/api/app/controllers/arvados/v1/jobs_controller.rb b/services/api/app/controllers/arvados/v1/jobs_controller.rb
index 178b48f..0a4e308 100644
--- a/services/api/app/controllers/arvados/v1/jobs_controller.rb
+++ b/services/api/app/controllers/arvados/v1/jobs_controller.rb
@@ -20,25 +20,33 @@ class Arvados::V1::JobsController < ApplicationController
                                  resource_attrs[:script_version],
                                  resource_attrs[:exclude_script_versions])
     if !resource_attrs[:nondeterministic] and !resource_attrs[:no_reuse]
-      # Search for jobs where the script_version is in the list of commits
+      # Search for jobs whose script_version is in the list of commits
       # returned by find_commit_range
       @object = nil
+      @incomplete_job = nil
       Job.readable_by(current_user).where(script: resource_attrs[:script],
                                           script_version: r).
         each do |j|
         if j.nondeterministic != true and
             j.success != false and
+            !j.cancelled_at and
             j.script_parameters == resource_attrs[:script_parameters]
-          # Record the first job in the list
-          if !@object
-            @object = j
-          end
-          # Ensure that all candidate jobs actually did produce the same output
-          if @object.output != j.output
-            @object = nil
-            break
+          if j.success.nil?
+            # We'll use this if we don't find a job that has completed
+            @incomplete_job ||= j
+          else
+            # Record the first job in the list
+            if !@object
+              @object = j
+            end
+            # Ensure that all candidate jobs actually did produce the same output
+            if @object.output != j.output
+              @object = nil
+              break
+            end
           end
         end
+        @object ||= @incomplete_job
         if @object
           return show
         end

commit 2d743356fb98a857f31be21eb398688d9ba96d71
Author: Tom Clegg <tom at curoverse.com>
Date:   Sat Apr 12 20:19:35 2014 -0400

    Ignore jobs with no repository specified, instead of crashing.

diff --git a/services/api/script/crunch-dispatch.rb b/services/api/script/crunch-dispatch.rb
index d9db69f..f15258d 100755
--- a/services/api/script/crunch-dispatch.rb
+++ b/services/api/script/crunch-dispatch.rb
@@ -37,7 +37,7 @@ class Dispatcher
   end
 
   def refresh_todo
-    @todo = Job.queue
+    @todo = Job.queue.select do |j| j.repository end
     @todo_pipelines = PipelineInstance.queue
   end
 

commit 085e614c8e7d1a29e675cf839a1ce9d92ffc5d5c
Author: Tom Clegg <tom at curoverse.com>
Date:   Sat Apr 12 20:09:01 2014 -0400

    Refactor pipeline_template -> pipeline_instance process.
    
    Copy components from template to instance during #create, not #show.
    
    Maintain script_parameters information in pipeline_instance. When
    editing, use that instead of relying on the original template.
    
    Add a generic "merge parameters in update" param, instead of altering
    default behavior for pipeline instances. Use Rails deep_merge instead
    of gem.
    
    Maintain original component order instead of applying tsort.

diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb
index c169be2..18a5d4f 100644
--- a/apps/workbench/app/controllers/application_controller.rb
+++ b/apps/workbench/app/controllers/application_controller.rb
@@ -108,8 +108,16 @@ class ApplicationController < ActionController::Base
   def update
     updates = params[@object.class.to_s.underscore.singularize.to_sym]
     updates.keys.each do |attr|
-      if @object.send(attr).is_a? Hash and updates[attr].is_a? String
-        updates[attr] = Oj.load updates[attr]
+      if @object.send(attr).is_a? Hash
+        if updates[attr].is_a? String
+          updates[attr] = Oj.load updates[attr]
+        end
+        if params[:merge] || params["merge_#{attr}".to_sym]
+          # Merge provided Hash with current Hash, instead of
+          # replacing.
+          updates[attr] = @object.send(attr).with_indifferent_access.
+            deep_merge(updates[attr].with_indifferent_access)
+        end
       end
     end
     if @object.update_attributes updates
diff --git a/apps/workbench/app/controllers/pipeline_instances_controller.rb b/apps/workbench/app/controllers/pipeline_instances_controller.rb
index 4231475..4853b0a 100644
--- a/apps/workbench/app/controllers/pipeline_instances_controller.rb
+++ b/apps/workbench/app/controllers/pipeline_instances_controller.rb
@@ -50,39 +50,18 @@ class PipelineInstancesController < ApplicationController
     return provenance, pips
   end
 
-  def show
-    if @object.components.empty? and @object.pipeline_template_uuid
+  def create
+    @object = PipelineInstance.new params[:pipeline_instance]
+    @object.save!
+    if !@object.components.andand.any? and @object.pipeline_template_uuid
       template = PipelineTemplate.find(@object.pipeline_template_uuid)
-      pipeline = {}
-      template.components.each do |component_name, component_props|
-        pipeline[component_name] = {}
-        component_props.each do |k, v|
-          if k == :script_parameters
-            pipeline[component_name][:script_parameters] = {}
-            v.each do |param_name, param_value|
-              if param_value.is_a? Hash
-                if param_value[:value]
-                  pipeline[component_name][:script_parameters][param_name] = param_value[:value]
-                elsif param_value[:default]
-                  pipeline[component_name][:script_parameters][param_name] = param_value[:default]
-                elsif param_value[:optional] != nil or param_value[:required] != nil or param_value[:dataclass] != nil
-                    pipeline[component_name][:script_parameters][param_name] = ""
-                else
-                  pipeline[component_name][:script_parameters][param_name] = param_value
-                end
-              else
-                pipeline[component_name][:script_parameters][param_name] = param_value
-              end
-            end
-          else
-            pipeline[component_name][k] = v
-          end
-        end
-      end
-      @object.components= pipeline
-      @object.save
+      @object.components = template.components.deep_dup
+      @object.save!
     end
+    super
+  end
 
+  def show
     @pipelines = [@object]
 
     if params[:compare]
@@ -181,15 +160,6 @@ class PipelineInstancesController < ApplicationController
     %w(Compare Graph)
   end 
 
-  def update
-    updates = params[@object.class.to_s.underscore.singularize.to_sym]
-    if updates["components"]
-      require 'deep_merge/rails_compat'
-      updates["components"] = updates["components"].deeper_merge(@object.components)
-    end
-    super
-  end
-
   def index
     @objects ||= model_class.limit(20).all
     super
diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb
index 9066224..5bae53d 100644
--- a/apps/workbench/app/helpers/application_helper.rb
+++ b/apps/workbench/app/helpers/application_helper.rb
@@ -109,49 +109,38 @@ module ApplicationHelper
     }.merge(htmloptions)
   end
 
-  def render_editable_subattribute(object, attr, subattr, template, htmloptions={})
-    if object
-      attrvalue = object.send(attr)
-      subattr.each do |k|
-        if attrvalue and attrvalue.is_a? Hash
-          attrvalue = attrvalue[k]
-        else
-          break
-        end
-      end
-    end
-
+  def render_pipeline_component_attribute(object, attr, subattr, value_info, htmloptions={})
     datatype = nil
     required = true
-    if template
-      #puts "Template is #{template.class} #{template.is_a? Hash} #{template}"
-      if template.is_a? Hash
-        if template[:output_of]
-          return raw("<span class='label label-default'>#{template[:output_of]}</span>")
-        end
-        if template[:dataclass]
-          dataclass = template[:dataclass]
-        end
-        if template[:optional] != nil
-          required = (template[:optional] != "true")
-        end
-        if template[:required] != nil
-          required = template[:required]
-        end
+    if value_info.is_a? Hash
+      if value_info[:output_of]
+        return raw("<span class='label label-default'>#{value_info[:output_of]}</span>")
+      end
+      if value_info[:dataclass]
+        dataclass = value_info[:dataclass]
+      end
+      if value_info[:optional] != nil
+        required = (value_info[:optional] != "true")
+      end
+      if value_info[:required] != nil
+        required = value_info[:required]
       end
     end
 
-    rsc = template
-    if template.is_a? Hash
-      if template[:value]
-        rsc = template[:value]
-      elsif template[:default]
-        rsc = template[:default]
+    attrvalue = value_info
+    if value_info.is_a? Hash
+      if value_info[:value]
+        attrvalue = value_info[:value]
+      elsif value_info[:default]
+        attrvalue = value_info[:default]
+      else
+        attrvalue = ''
       end
     end
 
-    return link_to_if_arvados_object(rsc) if !object
-    return link_to_if_arvados_object(attrvalue) if !object.attribute_editable? attr
+    unless object.andand.attribute_editable? attr
+      return link_to_if_arvados_object attrvalue
+    end
 
     if dataclass
       begin
@@ -159,23 +148,20 @@ module ApplicationHelper
       rescue NameError
       end
     else
-      dataclass = ArvadosBase.resource_class_for_uuid(rsc)
+      dataclass = ArvadosBase.resource_class_for_uuid(attrvalue)
     end
 
-    if dataclass && dataclass.is_a?(Class)
+    if dataclass.andand.is_a?(Class)
       datatype = 'select'
     elsif dataclass == 'number'
       datatype = 'number'
-    else
-      if template.is_a? Array
-        # ?!?
-      elsif template.is_a? String
-        if /^\d+$/.match(template)
-          datatype = 'number'
-        else
-          datatype = 'text'
-        end
-      end
+    elsif attrvalue.is_a? Array
+      datatype = 'text'
+      attrvalue = attrvalue.to_s
+    elsif attrvalue.is_a? Fixnum or attrvalue.is_a? Float
+      datatype = 'number'
+    elsif attrvalue.is_a? String
+      datatype = 'text'
     end
 
     id = "#{object.uuid}-#{subattr.join('-')}"
@@ -183,13 +169,12 @@ module ApplicationHelper
     subattr.each do |a|
       dn += "[#{a}]"
     end
-
-    if attrvalue.is_a? String
-      attrvalue = attrvalue.strip
+    if value_info.is_a? Hash
+      dn += '[value]'
     end
 
+    items = []
     if dataclass and dataclass.is_a? Class
-      items = []
       if attrvalue and !attrvalue.empty?
         items.append({name: attrvalue, uuid: attrvalue, type: dataclass.to_s})
       end
@@ -205,7 +190,7 @@ module ApplicationHelper
       "data-emptytext" => "none",
       "data-placement" => "bottom",
       "data-type" => datatype,
-      "data-url" => url_for(action: "update", id: object.uuid, controller: object.class.to_s.pluralize.underscore),
+      "data-url" => url_for(action: "update", id: object.uuid, controller: object.class.to_s.pluralize.underscore, merge: true),
       "data-title" => "Set value for #{subattr[-1].to_s}",
       "data-name" => dn,
       "data-pk" => "{id: \"#{object.uuid}\", key: \"#{object.class.to_s.underscore}\"}",
@@ -217,7 +202,7 @@ module ApplicationHelper
 
     lt += raw("\n<script>")
     
-    if items and items.length > 0
+    if items.any?
       lt += raw("add_form_selection_sources(#{items.to_json});\n")
     end
 
diff --git a/apps/workbench/app/helpers/pipeline_instances_helper.rb b/apps/workbench/app/helpers/pipeline_instances_helper.rb
index c52d339..bb0ff74 100644
--- a/apps/workbench/app/helpers/pipeline_instances_helper.rb
+++ b/apps/workbench/app/helpers/pipeline_instances_helper.rb
@@ -29,23 +29,7 @@ module PipelineInstancesHelper
     ret = []
     i = -1
 
-    comp = []
-
-    template = PipelineTemplate.find(@object.pipeline_template_uuid) rescue nil
-    if template
-      order = PipelineTemplatesHelper::sort_components(template.components)
-      order.each do |k|
-        if object.components[k]
-          comp.push([k, object.components[k]])
-        end
-      end
-    else
-      object.components.each do |k, v|
-        comp.push([k, v])
-      end
-    end
-
-    comp.each do |cname, c|
+    object.components.each do |cname, c|
       puts cname, c
       i += 1
       pj = {index: i, name: cname}
diff --git a/apps/workbench/app/helpers/pipeline_templates_helper.rb b/apps/workbench/app/helpers/pipeline_templates_helper.rb
deleted file mode 100644
index 0540047..0000000
--- a/apps/workbench/app/helpers/pipeline_templates_helper.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require 'tsort'
-
-class Hash
-  include TSort
-  def tsort_each_node(&block)
-    keys.sort.each(&block)
-  end
-
-  def tsort_each_child(node)
-    if self[node]
-      self[node][:script_parameters].sort.map do |k, v|
-        if v.is_a? Hash and v[:output_of]
-          yield v[:output_of].to_sym
-        end
-      end
-    end
-  end
-end
-
-module PipelineTemplatesHelper
-  def self.sort_components(components)
-    components.tsort
-  end
-end
diff --git a/apps/workbench/app/models/arvados_api_client.rb b/apps/workbench/app/models/arvados_api_client.rb
index 367a33e..39036bc 100644
--- a/apps/workbench/app/models/arvados_api_client.rb
+++ b/apps/workbench/app/models/arvados_api_client.rb
@@ -109,7 +109,7 @@ class ArvadosApiClient
   def unpack_api_response(j, kind=nil)
     if j.is_a? Hash and j[:items].is_a? Array and j[:kind].match(/(_list|List)$/)
       ary = j[:items].collect { |x| unpack_api_response x, j[:kind] }
-      ArvadosApiClient::patch_paging_vars(ary, j[:items_available], j[:offset], j[:limit])
+      self.class.patch_paging_vars(ary, j[:items_available], j[:offset], j[:limit])
     elsif j.is_a? Hash and (kind || j[:kind])
       oclass = self.kind_class(kind || j[:kind])
       if oclass
diff --git a/apps/workbench/app/views/pipeline_instances/_show_components.html.erb b/apps/workbench/app/views/pipeline_instances/_show_components.html.erb
index 119415b..07ca6f5 100644
--- a/apps/workbench/app/views/pipeline_instances/_show_components.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/_show_components.html.erb
@@ -99,6 +99,6 @@ setInterval(function(){$('a.refresh').click()}, 15000);
     <% end %>
   <% end %>
 
-  <%= render partial: 'pipeline_templates/show_components_template', locals: {:template => template, :obj => @object} %>
+  <%= render partial: 'show_components_editable', locals: {editable: true} %>
 
 <% end %>
diff --git a/apps/workbench/app/views/pipeline_instances/_show_components_editable.html.erb b/apps/workbench/app/views/pipeline_instances/_show_components_editable.html.erb
new file mode 100644
index 0000000..57c73fb
--- /dev/null
+++ b/apps/workbench/app/views/pipeline_instances/_show_components_editable.html.erb
@@ -0,0 +1,48 @@
+<table class="table pipeline-components-table" style="margin-top: -.1em">
+  <colgroup>
+    <col style="width: 15%" />
+    <col style="width: 20%" />
+    <col style="width: 20%" />
+    <col style="width: 45%" />
+  </colgroup>
+
+  <thead>
+    <tr>
+      <th>
+        component
+      </th><th>
+        script
+      </th><th>
+        parameter
+      </th><th>
+        value
+      </th>
+    </tr>
+  </thead>
+  <tbody>
+    <% @object.components.each do |k, component| %>
+      <% next if !component %>
+      <tr>
+        <td><span class="label label-default"><%= k %></span></td>
+
+        <td><%= render_pipeline_component_attribute (editable && @object), :components, [k, :script], component[:script] %></td>
+
+        <td>script version</td>
+
+        <td>
+          <%= render_pipeline_component_attribute (editable && @object), :components, [k, :script_version], component[:script_version] %>
+        </td>
+      </tr>
+
+      <% component[:script_parameters].andand.each do |p, tv| %>
+        <tr>
+          <td style="border-top: none"></td>
+          <td style="border-top: none"></td>
+
+          <td class="property-edit-row"><%= p %></td>
+          <td class="property-edit-row"><%= render_pipeline_component_attribute (editable && @object), :components, [k, :script_parameters, p.to_sym], tv %></td>
+        </tr>
+      <% end %>
+    <% end %>
+  </tbody>
+</table>
diff --git a/apps/workbench/app/views/pipeline_templates/_show_components.html.erb b/apps/workbench/app/views/pipeline_templates/_show_components.html.erb
index 0d34ba0..ef75b65 100644
--- a/apps/workbench/app/views/pipeline_templates/_show_components.html.erb
+++ b/apps/workbench/app/views/pipeline_templates/_show_components.html.erb
@@ -5,4 +5,4 @@
 <% end %>
 <% end %>
 
-<%= render partial: 'pipeline_templates/show_components_template', locals: {:template => @object, :obj => nil} %>
+<%= render partial: 'pipeline_instances/show_components_editable', locals: {editable: false} %>
diff --git a/apps/workbench/app/views/pipeline_templates/_show_components_template.html.erb b/apps/workbench/app/views/pipeline_templates/_show_components_template.html.erb
deleted file mode 100644
index 718c8c8..0000000
--- a/apps/workbench/app/views/pipeline_templates/_show_components_template.html.erb
+++ /dev/null
@@ -1,54 +0,0 @@
-<table class="table pipeline-components-table" style="margin-top: -.1em">
-  <colgroup>
-    <col style="width: 15%" />
-    <col style="width: 20%" />
-    <col style="width: 20%" />
-    <col style="width: 45%" />
-  </colgroup>
-
-  <thead>
-    <tr>
-      <th>
-        component
-      </th><th>
-        script
-      </th><th>
-        parameter
-      </th><th>
-        value
-      </th>
-    </tr>
-  </thead>
-  <tbody>
-    <% order = PipelineTemplatesHelper::sort_components(template.components) %>
-    <% puts "order is #{order}" %>
-    <% order.each do |k| %>
-      <% template_value = template.components[k] %>
-      <% puts "#{k} #{template_value}" %>
-      <% if not template_value then next end %>
-    <tr>
-      <td><span class="label label-default"><%= k %></span></td>
-
-      <td><%= render_editable_subattribute obj, :components, [k, :script], template_value[:script] %></td>
-
-      <td>script version</td>
-
-      <td>
-        <%= render_editable_subattribute obj, :components, [k, :script_version], template_value[:script_version] %>
-      </td>
-    </tr>
-
-    <% if template_value[:script_parameters].length > 0 %>
-      <% template_value[:script_parameters].each do |p, tv| %>
-        <tr>
-          <td style="border-top: none"></td>
-          <td style="border-top: none"></td>
-          
-          <td class="property-edit-row"><%= p %></td>
-          <td class="property-edit-row"><%= render_editable_subattribute obj, :components, [k, :script_parameters, p.to_sym], tv %></td>
-      <% end %>
-      </tr>
-    <% end %>
-  <% end %>
-  </tbody>
-</table>

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list