solid_stack_web 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3dbb76a6507f2e2a0480bafe3b9e18ac8f34777563c853911dfaf7b7f549f23
4
- data.tar.gz: 49f69c487ad4580d704ce122e46024ba96ff05c0c4b25166d64148128a28949d
3
+ metadata.gz: d97689a002516820708b4d0fcd852eadb94d4c24cd67b2d6d9760cc842df2033
4
+ data.tar.gz: 14bb1935a9b57b09768ddfd32677b5b16a447d13c96ac605c8bd4f7491412240
5
5
  SHA512:
6
- metadata.gz: aa1598c4f1ee1a527ccc5b50240e5c866274e848ad2e7245dfe02ef6f05a6b1b889a7eb88ce80cad46f72f1b7f533a858b47cb1a3d130fd300c8bb32698d9842
7
- data.tar.gz: 752a9f8176b029fa54f7c0dcef93081d4a6b25bc75dccebab67ae7561854ff3c5d1f9ae96804ac290841afbc38630b7329d0472b45fbaf7cbf95d3f342797b0b
6
+ metadata.gz: e2f8057a998ccc88c642f5805fd63e850b9e23e60f3b02b48685a55f64d30958e1e2775caae4dc59f58ca68f58e40539df0c282b844c2f196b18bcaa06999887
7
+ data.tar.gz: e4ecd5a93a76121efc58e5f66ae50ceaa9590b065af359b840c0d6f7622ee8f0417ad3ff397152672828c645b37826f8e51c7a3a4cf3da32d8c50a62d81c3d58
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![CI](https://github.com/eclectic-coding/solid_stack_web/actions/workflows/ci.yml/badge.svg)](https://github.com/eclectic-coding/solid_stack_web/actions/workflows/ci.yml)
4
4
  [![Gem Version](https://badge.fury.io/rb/solid_stack_web.svg)](https://badge.fury.io/rb/solid_stack_web)
5
+ [![Downloads](https://img.shields.io/gem/dt/solid_stack_web.svg)](https://rubygems.org/gems/solid_stack_web)
5
6
  [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.3-ruby)](https://www.ruby-lang.org)
6
7
  [![codecov](https://codecov.io/gh/eclectic-coding/solid_stack_web/branch/main/graph/badge.svg)](https://codecov.io/gh/eclectic-coding/solid_stack_web)
7
8
 
@@ -6,6 +6,7 @@ module SolidStackWeb
6
6
  @cable_stats = CableStats.new.to_h
7
7
  @throughput = ThroughputSparkline.new
8
8
  @failures = FailedJobSparkline.new
9
+ AlertWebhook.check(@queue_stats)
9
10
  end
10
11
  end
11
12
  end
@@ -82,10 +82,14 @@ module SolidStackWeb
82
82
 
83
83
  def jobs_csv
84
84
  CSV.generate(headers: true) do |csv|
85
- csv << %w[id class_name queue_name status priority enqueued_at]
85
+ headers = %w[id class_name queue_name status priority enqueued_at]
86
+ headers << "wait_time_seconds" if @status == "claimed"
87
+ csv << headers
86
88
  filtered_scope.each do |execution|
87
89
  job = execution.job
88
- csv << [job.id, job.class_name, job.queue_name, @status, job.priority, job.created_at.iso8601]
90
+ row = [job.id, job.class_name, job.queue_name, @status, job.priority, job.created_at.iso8601]
91
+ row << (execution.created_at - job.created_at).to_i if @status == "claimed"
92
+ csv << row
89
93
  end
90
94
  end
91
95
  end
@@ -39,6 +39,16 @@ module SolidStackWeb
39
39
  alerts << { type: "queue_depth", queue: queue_name.to_s, count: count, threshold: threshold } if count >= threshold
40
40
  end
41
41
 
42
+ if (job_threshold = SolidStackWeb.slow_job_threshold) && (count_threshold = SolidStackWeb.alert_slow_job_count_threshold)
43
+ count = ::SolidQueue::ClaimedExecution.where("created_at <= ?", job_threshold.seconds.ago).count
44
+ alerts << { type: "slow_jobs", count: count, threshold: count_threshold } if count >= count_threshold
45
+ end
46
+
47
+ if (threshold = SolidStackWeb.alert_stale_process_threshold)
48
+ count = @queue_stats[:processes_stale]
49
+ alerts << { type: "stale_processes", count: count, threshold: threshold } if count >= threshold
50
+ end
51
+
42
52
  alerts
43
53
  end
44
54
 
@@ -112,6 +112,7 @@
112
112
  <%= sort_header_th("Priority", "priority", sort_url, current_sort: @sort, current_dir: @direction) %>
113
113
  <%= sort_header_th("Enqueued At", "created_at", sort_url, current_sort: @sort, current_dir: @direction) %>
114
114
  <% if @status == "scheduled" %><th scope="col">Scheduled At</th><% end %>
115
+ <% if @status == "claimed" %><th scope="col">Wait Time</th><% end %>
115
116
  <th scope="col"><span class="sqw-sr-only">Actions</span></th>
116
117
  </tr>
117
118
  </thead>
@@ -132,6 +133,9 @@
132
133
  <% if @status == "scheduled" %>
133
134
  <td id="scheduled_at_<%= execution.id %>" class="sqw-muted"><%= local_time(execution.scheduled_at) %></td>
134
135
  <% end %>
136
+ <% if @status == "claimed" %>
137
+ <td class="sqw-monospace"><%= format_duration(execution.created_at - execution.job.created_at) %></td>
138
+ <% end %>
135
139
  <td class="sqw-actions">
136
140
  <% if @status == "scheduled" %>
137
141
  <%= button_to "Run Now", scheduled_job_path(execution),
@@ -41,11 +41,13 @@ SolidStackWeb.configure do |config|
41
41
  # Alert webhook — POST to this URL when a threshold is breached.
42
42
  # Delivery failures are silently swallowed; configure a cooldown to avoid storms.
43
43
  #
44
- # config.alert_webhook_url = "https://hooks.example.com/my-alert"
45
- # config.alert_failure_threshold = 10 # fire when failed jobs >= this
46
- # config.alert_queue_thresholds = { # fire when a queue's ready depth >= value
44
+ # config.alert_webhook_url = "https://hooks.example.com/my-alert"
45
+ # config.alert_failure_threshold = 10 # fire when failed jobs >= this
46
+ # config.alert_queue_thresholds = { # fire when a queue's ready depth >= value
47
47
  # "critical" => 50,
48
48
  # "default" => 500
49
49
  # }
50
- # config.alert_webhook_cooldown = 3600 # seconds between repeat alerts
50
+ # config.alert_slow_job_count_threshold = 3 # fire when N+ claimed jobs exceed slow_job_threshold duration
51
+ # config.alert_stale_process_threshold = 1 # fire when N+ workers have a stale heartbeat (>5 min old)
52
+ # config.alert_webhook_cooldown = 3600 # seconds between repeat alerts
51
53
  end
@@ -1,3 +1,3 @@
1
1
  module SolidStackWeb
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -6,6 +6,7 @@ module SolidStackWeb
6
6
  attr_writer :page_size, :connects_to, :slow_job_threshold,
7
7
  :alert_webhook_url, :alert_webhook_cooldown,
8
8
  :alert_failure_threshold, :alert_queue_thresholds,
9
+ :alert_slow_job_count_threshold, :alert_stale_process_threshold,
9
10
  :dashboard_refresh_interval, :default_refresh_interval,
10
11
  :search_results_limit, :allow_value_preview
11
12
 
@@ -37,6 +38,14 @@ module SolidStackWeb
37
38
  @alert_queue_thresholds || {}
38
39
  end
39
40
 
41
+ def alert_slow_job_count_threshold
42
+ @alert_slow_job_count_threshold
43
+ end
44
+
45
+ def alert_stale_process_threshold
46
+ @alert_stale_process_threshold
47
+ end
48
+
40
49
  def dashboard_refresh_interval
41
50
  @dashboard_refresh_interval || 5_000
42
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_stack_web
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith