[ARVADOS] updated: 47221ee04bee623850c559274b5ff64fe3068ae6

git at public.curoverse.com git at public.curoverse.com
Wed Oct 22 15:31:03 EDT 2014


Summary of changes:
 apps/workbench/app/assets/javascripts/event_log.js |  2 +-
 .../app/assets/javascripts/pipeline_instances.js   | 59 +++++-----------
 apps/workbench/app/assets/javascripts/tab_panes.js | 82 ++++++++++++++++++----
 .../workbench/app/assets/stylesheets/jobs.css.scss |  2 +-
 .../app/views/application/_content.html.erb        |  5 +-
 .../pipeline_instances/_show_components.html.erb   | 14 ++++
 .../_show_components_running.html.erb              |  9 ++-
 .../views/pipeline_instances/_show_log.html.erb    |  8 +--
 .../app/views/pipeline_instances/show.html.erb     |  6 +-
 9 files changed, 117 insertions(+), 70 deletions(-)

       via  47221ee04bee623850c559274b5ff64fe3068ae6 (commit)
      from  edac8924047fea353d579b5c4af91530ba54b053 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 47221ee04bee623850c559274b5ff64fe3068ae6
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Wed Oct 22 15:30:55 2014 -0400

    4084: Rework refresh event handling:
    * Tabs no longer refresh on log events by default
    * Added explicit 'arv-refresh-on-log-event' class to refresh panes
    * Pipeline log updates correctly from websockets again
    * Pipeline log now inspects pipeline updates and looks at components to update its list of events to listen for, no longer relies on contents of #Components tab
    * Pipeline log styling preserves whitespace, so the LobSTR can show up correctly
    * Log events now pass JSON object as event data, not the raw text

diff --git a/apps/workbench/app/assets/javascripts/event_log.js b/apps/workbench/app/assets/javascripts/event_log.js
index 8bfa1b0..a23c074 100644
--- a/apps/workbench/app/assets/javascripts/event_log.js
+++ b/apps/workbench/app/assets/javascripts/event_log.js
@@ -41,7 +41,7 @@ function onEventLogDispatcherMessage(event) {
 
   // if there are any listeners for this object uuid or "all", trigger the event
   matches = ".arv-log-event-listener[data-object-uuid=\"" + object_uuid + "\"],.arv-log-event-listener[data-object-uuids~=\"" + object_uuid + "\"],.arv-log-event-listener[data-object-uuid=\"all\"],.arv-log-event-listener[data-object-kind=\"" + parsedData.object_kind + "\"]";
-  $(matches).trigger('arv-log-event', event.data);
+  $(matches).trigger('arv-log-event', parsedData);
 }
 
 /* Automatically connect if there are any elements on the page that want to
diff --git a/apps/workbench/app/assets/javascripts/pipeline_instances.js b/apps/workbench/app/assets/javascripts/pipeline_instances.js
index 3c949f4..1868b38 100644
--- a/apps/workbench/app/assets/javascripts/pipeline_instances.js
+++ b/apps/workbench/app/assets/javascripts/pipeline_instances.js
@@ -48,51 +48,26 @@ $(document).on('ready ajax:complete', function() {
 });
 
 $(document).on('arv-log-event', '.arv-log-event-handler-append-logs', function(event, eventData){
-    var wasatbottom = ($(this).scrollTop() + $(this).height() >=
-                       this.scrollHeight);
-    var parsedData = JSON.parse(eventData);
-    var propertyText = undefined;
-    var properties = parsedData.properties;
+    var wasatbottom = ($(this).scrollTop() + $(this).height() >= this.scrollHeight);
 
-    if (properties !== null) {
-        propertyText = properties.text;
-    }
-    if (propertyText !== undefined) {
-        propertyText = propertyText.
-            replace(/\n$/, '').
-            replace(/\n/g, '<br/>');
-        $(this).append(propertyText + "<br/>");
-    } else if (parsedData.summary !== undefined) {
-        if (parsedData.summary.match(/^update of [-a-z0-9]{27}$/))
-            ; // Not helpful.
-        else
-            $(this).append(parsedData.summary + "<br/>");
+    if (eventData.event_type == "stderr" || eventData.event_type == "stdout") {
+        $(this).append(eventData.properties.text);
+    } else if (eventData.event_type == "create" || eventData.event_type == "update") {
+        if (eventData.object_kind == 'arvados#pipelineInstance') {
+            var objs = "";
+            var components = eventData.properties.new_attributes.components;
+            for (a in components) {
+                if (components[a].job && components[a].job.uuid) {
+                    objs += " " + components[a].job.uuid;
+                }
+            }
+            $(event.target).attr("data-object-uuids", eventData.object_uuid + objs);
+        }
     }
-    if (wasatbottom)
-        this.scrollTop = this.scrollHeight;
-}).on('arv:pane:loaded', '#Logs,#Log', function(){
-    $('.arv-log-event-handler-append-logs', this).each(function() {
+
+    if (wasatbottom) {
         this.scrollTop = this.scrollHeight;
-        $(this).closest('.tab-pane').on('arv:pane:reload', function(e) {
-            // Do not let this tab auto-refresh.
-            e.stopPropagation();
-        });
-    });
-}).on('ready ajax:complete', function(){
-    $(".arv-log-event-listener[data-object-uuids-live]").each(function() {
-        // Look at data-object-uuid attribute of elements matching
-        // given selector, so the event listener can listen for events
-        // that appeared on the page via ajax.
-        var $listener = $(this);
-        var have_uuids = '' + $listener.attr('data-object-uuids');
-        $($listener.attr('data-object-uuids-live')).each(function() {
-            var this_uuid = $(this).attr('data-object-uuid');
-            if (have_uuids.indexOf(this_uuid) == -1) {
-                have_uuids = have_uuids + ' ' + this_uuid;
-            }
-        });
-        $listener.attr('data-object-uuids', have_uuids);
-    });
+    }
 });
 
 var showhide_compare = function() {
diff --git a/apps/workbench/app/assets/javascripts/tab_panes.js b/apps/workbench/app/assets/javascripts/tab_panes.js
index cca49b2..7e2527e 100644
--- a/apps/workbench/app/assets/javascripts/tab_panes.js
+++ b/apps/workbench/app/assets/javascripts/tab_panes.js
@@ -1,19 +1,55 @@
 // Load tab panes on demand. See app/views/application/_content.html.erb
 
 // Fire when a tab is selected/clicked.
-$(document).on('shown.bs.tab', '[data-toggle="tab"]', function(e) {
-    $(this).trigger('arv:pane:reload');
+$(document).on('shown.bs.tab', '[data-toggle="tab"]', function(event) {
+    var tgt = $($(event.relatedTarget).attr('href'));
+    $(".pane-anchor", tgt).each(function (i, e) {
+        var a = $($(e).attr('href'));
+        a.removeClass("active");
+    });
+
+    tgt = $($(event.target).attr('href'));
+    $(".pane-anchor", tgt).each(function (i, e) {
+        var a = $($(e).attr('href'));
+        a.addClass("active");
+    });
+
+    $(event.target).trigger('arv:pane:reload');
 });
 
-// Fire when the content in a pane becomes stale/dirty. If the pane is
-// 'active', reload it right away. Otherwise, just replace the current content
-// with a spinner for now, don't load the new content unless/until the pane
-// becomes active.
+// Ask a refreshable pane to reload via ajax.
+// Target of this event is the anchoring element that manages the pane.
+// Panes can be in one of four states: not loaded (no state classes), pane-loading, pane-loading+pane-stale, pane-loaded
 $(document).on('arv:pane:reload', function(e) {
-    // Unload a single pane. Reload it if it's active.
-    $(e.target).removeClass('loaded');
+    e.stopPropagation();
+
+    if ($(e.target).hasClass('pane-loading')) {
+        // Already loading, mark stale to schedule a reload after this one.
+        console.log(e.target.id + " stale");
+        $(e.target).addClass('pane-stale');
+        return;
+    }
+
+    var throttle = $(e.target).attr('data-load-throttle');
+    if (throttle) {
+        var now = (new Date()).getTime();
+        var loaded_at = $(e.target).attr('data-loaded-at');
+        if (loaded_at && (now - loaded_at) < throttle) {
+            setTimeout(function() {
+                $(e.target).trigger('arv:pane:reload');
+            });
+            return;
+        }
+    }
+
     var $pane = $($(e.target).attr('href'));
     if ($pane.hasClass('active')) {
+        console.log(e.target.id + " loading");
+
+        $(e.target).removeClass('pane-loaded');
+        $(e.target).removeClass('pane-stale');
+        $(e.target).addClass('pane-loading');
+
         var content_url = $(e.target).attr('data-pane-content-url');
         $.ajax(content_url, {dataType: 'html', type: 'GET', context: $pane}).
             done(function(data, status, jqxhr) {
@@ -31,8 +67,16 @@ $(document).on('arv:pane:reload', function(e) {
                     }
                 });
                 $pane.html(tmp);
-                $(e.target).addClass('loaded');
+                $(e.target).removeClass('pane-loading');
+                $(e.target).addClass('pane-loaded');
+                $(e.target).attr('data-loaded-at', (new Date()).getTime());
                 $pane.trigger('arv:pane:loaded');
+
+                console.log(e.target.id + " loaded");
+
+                if ($(e.target).hasClass('pane-stale')) {
+                    $(e.target).trigger('arv:pane:reload');
+                }
             }).fail(function(jqxhr, status, error) {
                 var errhtml;
                 if (jqxhr.getResponseHeader('Content-Type').match(/\btext\/html\b/)) {
@@ -68,18 +112,30 @@ $(document).on('arv:pane:reload', function(e) {
                     $('body', iframe.contentDocument).html(errhtml);
                     iframe.height = iframe.contentDocument.body.scrollHeight + "px";
                 }, 1);
-                $(e.target).addClass('loaded');
+                $(e.target).addClass('pane-loaded');
             });
     } else {
+        console.log($(e.target).attr('href') + " is not active");
         // When the user selects e.target tab, show a spinner instead of
         // old content while loading.
+        $(e.target).removeClass('pane-loading');
+        $(e.target).removeClass('pane-loaded');
+        $(e.target).removeClass('pane-stale');
+
         $pane.html('<div class="spinner spinner-32px spinner-h-center"></div>');
     }
 });
 
-// Mark all panes as stale/dirty. Refresh the active pane.
-$(document).on('arv-log-event arv:pane:reload:all', function() {
-    $('.pane-anchor.loaded').trigger('arv:pane:reload');
+// Mark all panes as stale/dirty. Refresh any 'active' panes.
+$(document).on('arv:pane:reload:all', function() {
+    $('.pane-anchor').trigger('arv:pane:reload');
+});
+
+$(document).on('ready ajax:complete', function() {
+    // Panes marked arv-refresh-on-log-event should be refreshed
+    $('.pane-anchor.arv-refresh-on-log-event').on('arv-log-event', function(e) {
+        $(e.target).trigger('arv:pane:reload');
+    });
 });
 
 // If there is a 'tab counts url' in the nav-tabs element then use it to get some javascript that will update them
diff --git a/apps/workbench/app/assets/stylesheets/jobs.css.scss b/apps/workbench/app/assets/stylesheets/jobs.css.scss
index b25c04a..f76c70b 100644
--- a/apps/workbench/app/assets/stylesheets/jobs.css.scss
+++ b/apps/workbench/app/assets/stylesheets/jobs.css.scss
@@ -1,6 +1,6 @@
 .arv-job-log-window {
     height: 40em;
-    white-space: nowrap;
+    white-space: pre;
     overflow: scroll;
     background: black;
     color: white;
diff --git a/apps/workbench/app/views/application/_content.html.erb b/apps/workbench/app/views/application/_content.html.erb
index e9fec77..632a291 100644
--- a/apps/workbench/app/views/application/_content.html.erb
+++ b/apps/workbench/app/views/application/_content.html.erb
@@ -23,14 +23,14 @@
     <% pane_list.each_with_index do |pane, i| %>
       <% pane_name = (pane.is_a?(Hash) ? pane[:name] : pane) %>
       <div id="<%= pane_name %>"
-           class="tab-pane fade <%= 'in active loaded' if i==0 %> arv-log-event-listener"
+           class="tab-pane <%= 'in active loaded' if i==0 %>"
            <% if controller.action_name == "index" %>
              data-object-kind="arvados#<%= ArvadosApiClient.class_kind controller.model_class %>"
            <% else %>
              data-object-uuid="<%= @object.uuid %>"
            <% end %>
+           style="margin-top:0.5em;"
       >
-        <div id="<%= pane_name %>-scroll" style="margin-top:0.5em;">
           <div class="pane-content">
             <% if i == 0 %>
               <%= render_pane pane_name, to_string: true %>
@@ -38,7 +38,6 @@
               <div class="spinner spinner-32px spinner-h-center"></div>
             <% end %>
           </div>
-        </div>
       </div>
     <% end %>
   </div>
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 94cbf98..94823a2 100644
--- a/apps/workbench/app/views/pipeline_instances/_show_components.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/_show_components.html.erb
@@ -10,8 +10,22 @@
     </span> 
   </div>
 
+<% job_uuids = @object.components.map { |k,j| j[:job].andand[:uuid] }.compact %>
+
+<div id="pipeline-instance-components"
+     class="pane-anchor arv-log-event-listener arv-refresh-on-log-event"
+     href="#pipeline-instance-components-pane"
+     data-pane-content-url="<%= url_for(params.merge(tab_pane: "components_running")) %>"
+     data-object-uuids="<%= @object.uuid %> <%= job_uuids.join(' ') %>"
+     data-load-throttle="5000"
+     >
+  <div id="pipeline-instance-components-pane" class="active">
+
   <%= render_pipeline_components("running", :json) %>
 
+</div>
+</div>
+
 <% else %>
   <%# state is either New or Ready %>
   <p><i>Here are all of the pipeline's components (jobs that will need to run in order to complete the pipeline). If you know what you're doing (or you're experimenting) you can modify these parameters before starting the pipeline. Usually, you only need to edit the settings presented on the "Inputs" tab above.</i></p>
diff --git a/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb b/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb
index 165a694..12eda27 100644
--- a/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/_show_components_running.html.erb
@@ -1,5 +1,8 @@
 <%# Summary %>
 
+<% pipeline_jobs = render_pipeline_jobs %>
+<% job_uuids = pipeline_jobs.map { |j| j[:job].andand[:uuid] }.compact %>
+
 <% if @object.state == 'Paused' %>
   <p>
     This pipeline is paused.  Jobs that are
@@ -7,8 +10,8 @@
   </p>
 <% end %>
 
-<% tasks = JobTask.filter([['job_uuid', 'in', render_pipeline_jobs.map { |j| j[:job].andand[:uuid] }.compact]]).results %>
-<% runningtime = determine_wallclock_runtime(render_pipeline_jobs.map {|j| j[:job]}.compact) %>
+<% tasks = JobTask.filter([['job_uuid', 'in', job_uuids]]).results %>
+<% runningtime = determine_wallclock_runtime(pipeline_jobs.map {|j| j[:job]}.compact) %>
 
 <p>
   <% if @object.started_at %>
@@ -68,6 +71,6 @@
 
 <%# Components %>
 
-<% render_pipeline_jobs.each_with_index do |pj, i| %>
+<% pipeline_jobs.each_with_index do |pj, i| %>
   <%= render partial: 'running_component', locals: {tasks: tasks, pj: pj, i: i, expanded: false} %>
 <% end %>
diff --git a/apps/workbench/app/views/pipeline_instances/_show_log.html.erb b/apps/workbench/app/views/pipeline_instances/_show_log.html.erb
index 2fdb45b..39625b6 100644
--- a/apps/workbench/app/views/pipeline_instances/_show_log.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/_show_log.html.erb
@@ -1,6 +1,4 @@
-<% log_history = stderr_log_history([@object.uuid] + pipeline_jobs(@object).collect{|x|x[:job].andand[:uuid]}.compact) %>
-<div class="arv-log-event-listener arv-log-event-handler-append-logs arv-job-log-window" id="pipeline_event_log_div" data-object-uuids="<%= @object.uuid %>" data-object-uuids-live="#Components tr[data-object-uuid]">
-  <% log_history.each do |entry| %>
-    <%=entry%><br/>
-  <% end %>
+<% log_uuids = [@object.uuid] + pipeline_jobs(@object).collect{|x|x[:job].andand[:uuid]}.compact %>
+<% log_history = stderr_log_history(log_uuids) %>
+<div class="arv-log-event-listener arv-log-event-handler-append-logs arv-job-log-window" id="pipeline_event_log_div" data-object-uuids="<%= log_uuids.join(' ') %>"><%= log_history.join("\n") %>
 </div>
diff --git a/apps/workbench/app/views/pipeline_instances/show.html.erb b/apps/workbench/app/views/pipeline_instances/show.html.erb
index 0b72f69..12b291f 100644
--- a/apps/workbench/app/views/pipeline_instances/show.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/show.html.erb
@@ -18,14 +18,16 @@
 <% content_for :tab_line_buttons do %>
 
   <div id="pipeline-instance-tab-buttons"
-       class="pane-anchor loaded"
+       class="pane-anchor active arv-log-event-listener arv-refresh-on-pipeline-state-change"
        href="#pipeline-instance-tab-buttons-pane"
        data-pane-content-url="<%= url_for(params.merge(tab_pane: "tab_buttons")) %>"
+       data-object-uuid="<%= @object.uuid %>"
        >
-    <div id="pipeline-instance-tab-buttons-pane" class="active">
+    <div id="pipeline-instance-tab-buttons-pane">
       <%= render partial: 'show_tab_buttons', locals: {object: @object}%>
     </div>
   </div>
+
 <% end %>
 
 <%= render partial: 'content', layout: 'content_layout', locals: {pane_list: controller.show_pane_list }%>

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list