Merge pull request #583 from knu/highlight_new_events

Make event-indicator a link to the events page, with new events highlighted

Akinori MUSHA лет %!s(int64=10): %!d(string=назад)
Родитель
Сommit
9b5510131a

+ 12 - 10
app/assets/javascripts/components/worker-checker.js.coffee

@@ -1,10 +1,15 @@
1 1
 $ ->
2
-  firstEventCount = null
2
+  sinceId = null
3 3
   previousJobs = null
4 4
 
5 5
   if $(".job-indicator").length
6 6
     check = ->
7
-      $.getJSON "/worker_status", (json) ->
7
+      query =
8
+        if sinceId?
9
+          '?since_id=' + sinceId
10
+        else
11
+          ''
12
+      $.getJSON "/worker_status" + query, (json) ->
8 13
         for method in ['pending', 'awaiting_retry', 'recent_failures']
9 14
           count = json[method]
10 15
           elem = $(".job-indicator[role=#{method}]")
@@ -23,16 +28,17 @@ $ ->
23 28
             if elem.is(":visible")
24 29
               elem.tooltip('destroy').fadeOut()
25 30
 
26
-        firstEventCount = json.event_count unless firstEventCount?
27
-        if firstEventCount? && json.event_count > firstEventCount
31
+        if sinceId? && json.event_count > 0
28 32
           $("#event-indicator").tooltip('destroy').
29
-                                tooltip(title: "Click to reload", delay: 0, placement: "bottom", trigger: "hover").
33
+                                tooltip(title: "Click to see the events", delay: 0, placement: "bottom", trigger: "hover").
34
+                                find('a').attr(href: json.events_url).end().
30 35
                                 fadeIn().
31 36
                                 find(".number").
32
-                                text(json.event_count - firstEventCount)
37
+                                text(json.event_count)
33 38
         else
34 39
           $("#event-indicator").tooltip('destroy').fadeOut()
35 40
 
41
+        sinceId ?= json.max_id
36 42
         currentJobs = [json.pending, json.awaiting_retry, json.recent_failures]
37 43
         if document.location.pathname == '/jobs' && $(".modal[aria-hidden=false]").length == 0 && previousJobs? && previousJobs.join(',') != currentJobs.join(',')
38 44
           $.get '/jobs', (data) =>
@@ -42,7 +48,3 @@ $ ->
42 48
         window.workerCheckTimeout = setTimeout check, 2000
43 49
 
44 50
     check()
45
-
46
-  $("#event-indicator a").on "click", (e) ->
47
-    e.preventDefault()
48
-    window.location.reload()

+ 14 - 0
app/assets/stylesheets/tables.css.scss

@@ -20,6 +20,20 @@
20 20
   }
21 21
 }
22 22
 
23
+.table-striped > tbody > tr.hl {
24
+  &:nth-child(odd) {
25
+    > td, > th {
26
+      background-color: #ffeecc;
27
+    }
28
+  }
29
+
30
+  &:nth-child(even) {
31
+    > td, > th {
32
+      background-color: #f9e8c6;
33
+    }
34
+  }
35
+}
36
+
23 37
 table.events {
24 38
   .payload {
25 39
     color: #999;

+ 27 - 7
app/controllers/worker_status_controller.rb

@@ -1,12 +1,32 @@
1 1
 class WorkerStatusController < ApplicationController
2 2
   def show
3
-    start = Time.now.to_f
4
-    render :json => {
5
-        :pending => Delayed::Job.where("run_at <= ? AND locked_at IS NULL AND attempts = 0", Time.now).count,
6
-        :awaiting_retry => Delayed::Job.where("failed_at IS NULL AND attempts > 0").count,
7
-        :recent_failures => Delayed::Job.where("failed_at IS NOT NULL AND failed_at > ?", 5.days.ago).count,
8
-        :event_count => current_user.events.count,
9
-        :compute_time => Time.now.to_f - start
3
+    start = Time.now
4
+    events = current_user.events
5
+
6
+    if params[:since_id].present?
7
+      since_id = params[:since_id].to_i
8
+      events = events.where('id > ?', since_id)
9
+    end
10
+
11
+    result = events.select('COUNT(id) AS count', 'MIN(id) AS min_id', 'MAX(id) AS max_id').first
12
+    count, min_id, max_id = result.count, result.min_id, result.max_id
13
+
14
+    case max_id
15
+    when nil
16
+    when min_id
17
+      events_url = events_path(hl: max_id)
18
+    else
19
+      events_url = events_path(hl: "#{min_id}-#{max_id}")
20
+    end
21
+
22
+    render json: {
23
+      pending: Delayed::Job.pending.where("run_at <= ?", start).count,
24
+      awaiting_retry: Delayed::Job.awaiting_retry.count,
25
+      recent_failures: Delayed::Job.failed.where('failed_at > ?', 5.days.ago).count,
26
+      event_count: count,
27
+      max_id: max_id || 0,
28
+      events_url: events_url,
29
+      compute_time: Time.now - start
10 30
     }
11 31
   end
12 32
 end

+ 21 - 0
app/helpers/application_helper.rb

@@ -71,4 +71,25 @@ module ApplicationHelper
71 71
       service_label_text(service)
72 72
     ].join.html_safe, class: "label label-default label-service service-#{service.provider}"
73 73
   end
74
+
75
+  def highlighted?(id)
76
+    @highlighted_ranges ||=
77
+      case value = params[:hl].presence
78
+      when String
79
+        value.split(/,/).flat_map { |part|
80
+          case part
81
+          when /\A(\d+)\z/
82
+            (part.to_i)..(part.to_i)
83
+          when /\A(\d+)?-(\d+)?\z/
84
+            ($1 ? $1.to_i : 1)..($2 ? $2.to_i : Float::INFINITY)
85
+          else
86
+            []
87
+          end
88
+        }
89
+      else
90
+        []
91
+      end
92
+
93
+    @highlighted_ranges.any? { |range| range.cover?(id) }
94
+  end
74 95
 end

+ 3 - 3
app/views/events/index.html.erb

@@ -18,7 +18,7 @@
18 18
 
19 19
         <% @events.each do |event| %>
20 20
           <% next unless event.agent %>
21
-          <tr>
21
+          <%= content_tag :tr, class: (highlighted?(event.id) ? 'hl' : nil) do %>
22 22
             <td><%= link_to event.agent.name, agent_path(event.agent) %></td>
23 23
             <td title='<%= event.created_at %>'><%= time_ago_in_words event.created_at %> ago</td>
24 24
             <td class='payload'><%= truncate event.payload.to_json, :length => 90, :omission => "" %></td>
@@ -29,12 +29,12 @@
29 29
                 <%= link_to 'Delete', event_path(event), method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-default" %>
30 30
               </div>
31 31
             </td>
32
-          </tr>
32
+          <% end %>
33 33
         <% end %>
34 34
         </table>
35 35
       </div>
36 36
 
37
-      <%= paginate @events, :theme => 'twitter-bootstrap-3' %>
37
+      <%= paginate @events, params: params.slice(:hl), theme: 'twitter-bootstrap-3' %>
38 38
 
39 39
       <br />
40 40
 

+ 6 - 0
config/initializers/delayed_job.rb

@@ -7,3 +7,9 @@ Delayed::Worker.delay_jobs = !Rails.env.test?
7 7
 
8 8
 # Delayed::Worker.logger = Logger.new(Rails.root.join('log', 'delayed_job.log'))
9 9
 # Delayed::Worker.logger.level = Logger::DEBUG
10
+
11
+class Delayed::Job
12
+  scope :pending, ->{ where("locked_at IS NULL AND attempts = 0") }
13
+  scope :awaiting_retry, ->{ where("failed_at IS NULL AND attempts > 0") }
14
+  scope :failed, -> { where("failed_at IS NOT NULL") }
15
+end

+ 32 - 0
spec/helpers/application_helper_spec.rb

@@ -143,4 +143,36 @@ describe ApplicationHelper do
143 143
       expect(elem).to be_a Nokogiri::XML::Element
144 144
     end
145 145
   end
146
+
147
+  describe '#highlighted?' do
148
+    it 'understands hl=6-8' do
149
+      stub(params).[](:hl) { '6-8' }
150
+      expect((1..10).select { |i| highlighted?(i) }).to eq [6, 7, 8]
151
+    end
152
+
153
+    it 'understands hl=1,3-4,9' do
154
+      stub(params).[](:hl) { '1,3-4,9' }
155
+      expect((1..10).select { |i| highlighted?(i) }).to eq [1, 3, 4, 9]
156
+    end
157
+
158
+    it 'understands hl=8-' do
159
+      stub(params).[](:hl) { '8-' }
160
+      expect((1..10).select { |i| highlighted?(i) }).to eq [8, 9, 10]
161
+    end
162
+
163
+    it 'understands hl=-2' do
164
+      stub(params).[](:hl) { '-2' }
165
+      expect((1..10).select { |i| highlighted?(i) }).to eq [1, 2]
166
+    end
167
+
168
+    it 'understands hl=-' do
169
+      stub(params).[](:hl) { '-' }
170
+      expect((1..10).select { |i| highlighted?(i) }).to eq [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
171
+    end
172
+
173
+    it 'is OK with no hl' do
174
+      stub(params).[](:hl) { nil }
175
+      expect((1..10).select { |i| highlighted?(i) }).to be_empty
176
+    end
177
+  end
146 178
 end