roundhouse_ui 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +166 -0
- data/Rakefile +3 -0
- data/app/assets/javascripts/roundhouse_ui/turbo.min.js +35 -0
- data/app/assets/stylesheets/roundhouse_ui/application.css +15 -0
- data/app/controllers/concerns/roundhouse_ui/job_set_browsing.rb +41 -0
- data/app/controllers/roundhouse_ui/application_controller.rb +75 -0
- data/app/controllers/roundhouse_ui/assets_controller.rb +16 -0
- data/app/controllers/roundhouse_ui/audit_controller.rb +7 -0
- data/app/controllers/roundhouse_ui/busy_controller.rb +29 -0
- data/app/controllers/roundhouse_ui/capsules_controller.rb +27 -0
- data/app/controllers/roundhouse_ui/dashboard_controller.rb +26 -0
- data/app/controllers/roundhouse_ui/dead_controller.rb +46 -0
- data/app/controllers/roundhouse_ui/errors_controller.rb +50 -0
- data/app/controllers/roundhouse_ui/jobs_controller.rb +94 -0
- data/app/controllers/roundhouse_ui/metrics_controller.rb +8 -0
- data/app/controllers/roundhouse_ui/queues_controller.rb +40 -0
- data/app/controllers/roundhouse_ui/redis_controller.rb +21 -0
- data/app/controllers/roundhouse_ui/retries_controller.rb +34 -0
- data/app/controllers/roundhouse_ui/scheduled_controller.rb +34 -0
- data/app/controllers/roundhouse_ui/snapshots_controller.rb +26 -0
- data/app/controllers/roundhouse_ui/workers_controller.rb +33 -0
- data/app/helpers/roundhouse_ui/application_helper.rb +4 -0
- data/app/helpers/roundhouse_ui/nav_helper.rb +24 -0
- data/app/helpers/roundhouse_ui/observability_helper.rb +13 -0
- data/app/views/layouts/roundhouse_ui/application.html.erb +365 -0
- data/app/views/roundhouse_ui/audit/index.html.erb +21 -0
- data/app/views/roundhouse_ui/busy/index.html.erb +23 -0
- data/app/views/roundhouse_ui/capsules/index.html.erb +22 -0
- data/app/views/roundhouse_ui/dashboard/show.html.erb +68 -0
- data/app/views/roundhouse_ui/dead/index.html.erb +46 -0
- data/app/views/roundhouse_ui/errors/index.html.erb +28 -0
- data/app/views/roundhouse_ui/jobs/_form.html.erb +24 -0
- data/app/views/roundhouse_ui/jobs/edit.html.erb +2 -0
- data/app/views/roundhouse_ui/jobs/new.html.erb +2 -0
- data/app/views/roundhouse_ui/jobs/show.html.erb +33 -0
- data/app/views/roundhouse_ui/metrics/show.html.erb +49 -0
- data/app/views/roundhouse_ui/queues/index.html.erb +45 -0
- data/app/views/roundhouse_ui/redis/show.html.erb +59 -0
- data/app/views/roundhouse_ui/retries/index.html.erb +33 -0
- data/app/views/roundhouse_ui/scheduled/index.html.erb +29 -0
- data/app/views/roundhouse_ui/shared/_pager.html.erb +15 -0
- data/app/views/roundhouse_ui/snapshots/index.html.erb +25 -0
- data/app/views/roundhouse_ui/workers/index.html.erb +39 -0
- data/config/routes.rb +54 -0
- data/lib/roundhouse_ui/audit.rb +25 -0
- data/lib/roundhouse_ui/cancel_middleware.rb +19 -0
- data/lib/roundhouse_ui/cancellation.rb +37 -0
- data/lib/roundhouse_ui/engine.rb +5 -0
- data/lib/roundhouse_ui/fetch.rb +36 -0
- data/lib/roundhouse_ui/metrics.rb +51 -0
- data/lib/roundhouse_ui/observability.rb +46 -0
- data/lib/roundhouse_ui/pause.rb +59 -0
- data/lib/roundhouse_ui/redaction.rb +33 -0
- data/lib/roundhouse_ui/snapshots.rb +90 -0
- data/lib/roundhouse_ui/version.rb +3 -0
- data/lib/roundhouse_ui.rb +73 -0
- data/lib/tasks/roundhouse_ui_tasks.rake +4 -0
- metadata +131 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "set"
|
|
2
|
+
require "sidekiq"
|
|
3
|
+
|
|
4
|
+
module RoundhouseUi
|
|
5
|
+
# Roundhouse's own queue-pause registry — pure OSS, no Sidekiq Pro.
|
|
6
|
+
#
|
|
7
|
+
# Paused queue names live in a Redis set. RoundhouseUi::Fetch consults this set
|
|
8
|
+
# and skips paused queues when pulling work, so a paused queue stops being
|
|
9
|
+
# consumed without stopping the worker process.
|
|
10
|
+
module Pause
|
|
11
|
+
KEY = "roundhouse:paused"
|
|
12
|
+
FETCH_FLAG = "roundhouse:fetch_alive" # liveness beacon set by the fetcher
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def pause!(queue)
|
|
17
|
+
Sidekiq.redis { |conn| conn.call("SADD", KEY, queue.to_s) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def unpause!(queue)
|
|
21
|
+
Sidekiq.redis { |conn| conn.call("SREM", KEY, queue.to_s) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def paused?(queue)
|
|
25
|
+
Sidekiq.redis { |conn| conn.call("SISMEMBER", KEY, queue.to_s) } == 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def paused_queues
|
|
29
|
+
Sidekiq.redis { |conn| conn.call("SMEMBERS", KEY) }.sort
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def paused_set
|
|
33
|
+
Set.new(Sidekiq.redis { |conn| conn.call("SMEMBERS", KEY) })
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Given the redis queue keys BasicFetch would poll (e.g. "queue:default"),
|
|
37
|
+
# drop any whose queue is paused. Pure given the paused set, so it's unit
|
|
38
|
+
# testable without a running Sidekiq.
|
|
39
|
+
def reject_paused(queue_keys)
|
|
40
|
+
paused = paused_set
|
|
41
|
+
return queue_keys if paused.empty?
|
|
42
|
+
|
|
43
|
+
queue_keys.reject { |key| paused.include?(key.to_s.delete_prefix("queue:")) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The fetcher calls this periodically so the web UI can tell whether pausing
|
|
47
|
+
# is actually enforced (the worker and web run in separate processes). The
|
|
48
|
+
# short TTL means the flag disappears soon after all Roundhouse fetchers stop.
|
|
49
|
+
def mark_fetch_alive!(ttl = 30)
|
|
50
|
+
Sidekiq.redis { |conn| conn.call("SET", FETCH_FLAG, "1", "EX", ttl) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# True when a RoundhouseUi::Fetch has reported in recently — i.e. pausing
|
|
54
|
+
# will take effect. When false, the UI warns instead of pretending.
|
|
55
|
+
def fetch_installed?
|
|
56
|
+
Sidekiq.redis { |conn| conn.call("EXISTS", FETCH_FLAG) } == 1
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module RoundhouseUi
|
|
2
|
+
# Masks sensitive values when displaying job arguments. Configure the key
|
|
3
|
+
# patterns to redact (matched case-insensitively as substrings):
|
|
4
|
+
#
|
|
5
|
+
# RoundhouseUi.redact_args = %w[password token secret api_key authorization]
|
|
6
|
+
#
|
|
7
|
+
# Walks arrays/hashes so nested keyword args are covered. No-op by default.
|
|
8
|
+
module Redaction
|
|
9
|
+
MASK = "«redacted»".freeze
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
def apply(value, patterns = RoundhouseUi.redact_args)
|
|
14
|
+
return value if patterns.nil? || patterns.empty?
|
|
15
|
+
|
|
16
|
+
case value
|
|
17
|
+
when Hash
|
|
18
|
+
value.each_with_object({}) do |(k, v), out|
|
|
19
|
+
out[k] = sensitive?(k, patterns) ? MASK : apply(v, patterns)
|
|
20
|
+
end
|
|
21
|
+
when Array
|
|
22
|
+
value.map { |e| apply(e, patterns) }
|
|
23
|
+
else
|
|
24
|
+
value
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def sensitive?(key, patterns)
|
|
29
|
+
key = key.to_s.downcase
|
|
30
|
+
patterns.any? { |p| key.include?(p.to_s.downcase) }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "sidekiq/api"
|
|
3
|
+
|
|
4
|
+
module RoundhouseUi
|
|
5
|
+
# Back up a queue's jobs before you purge it, and restore them later — the
|
|
6
|
+
# safety net that makes clearing a stuck queue non-destructive.
|
|
7
|
+
#
|
|
8
|
+
# Storage is pluggable via RoundhouseUi.snapshot_store. The default RedisStore
|
|
9
|
+
# keeps blobs in Redis (simple, dependency-free); for large/stuck queues you'll
|
|
10
|
+
# want a file or S3 store so the backup doesn't sit in the same Redis you're
|
|
11
|
+
# trying to relieve. Any object responding to write/read/delete/ids works.
|
|
12
|
+
module Snapshots
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
def store
|
|
16
|
+
RoundhouseUi.snapshot_store
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Copy every job currently on `queue_name` into a snapshot. Non-destructive —
|
|
20
|
+
# the queue is left untouched (purge separately if you want to clear it).
|
|
21
|
+
def take(queue_name)
|
|
22
|
+
payloads = []
|
|
23
|
+
Sidekiq::Queue.new(queue_name).each { |job| payloads << job.value }
|
|
24
|
+
|
|
25
|
+
id = "#{queue_name}-#{Time.now.to_i}-#{rand(10_000)}"
|
|
26
|
+
store.write(id, JSON.dump(
|
|
27
|
+
"queue" => queue_name, "created_at" => Time.now.to_f, "count" => payloads.size, "jobs" => payloads
|
|
28
|
+
))
|
|
29
|
+
metadata(id)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def all
|
|
33
|
+
store.ids.filter_map { |id| metadata(id) }.sort_by { |m| -m[:created_at].to_f }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def metadata(id)
|
|
37
|
+
raw = store.read(id)
|
|
38
|
+
return nil unless raw
|
|
39
|
+
|
|
40
|
+
data = JSON.parse(raw)
|
|
41
|
+
{ id: id, queue: data["queue"], count: data["count"] || data["jobs"].size, created_at: data["created_at"] }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Re-enqueue a snapshot's jobs onto their original queue. Returns the count.
|
|
45
|
+
def restore(id)
|
|
46
|
+
raw = store.read(id)
|
|
47
|
+
return 0 unless raw
|
|
48
|
+
|
|
49
|
+
data = JSON.parse(raw)
|
|
50
|
+
key = "queue:#{data["queue"]}"
|
|
51
|
+
data["jobs"].each { |payload| Sidekiq.redis { |conn| conn.call("RPUSH", key, payload) } }
|
|
52
|
+
data["jobs"].size
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def delete(id)
|
|
56
|
+
store.delete(id)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Default store: blobs + an index set, all in Redis.
|
|
60
|
+
class RedisStore
|
|
61
|
+
INDEX = "roundhouse:snapshots"
|
|
62
|
+
|
|
63
|
+
def write(id, blob)
|
|
64
|
+
Sidekiq.redis do |conn|
|
|
65
|
+
conn.call("SET", key(id), blob)
|
|
66
|
+
conn.call("SADD", INDEX, id)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def read(id)
|
|
71
|
+
Sidekiq.redis { |conn| conn.call("GET", key(id)) }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def delete(id)
|
|
75
|
+
Sidekiq.redis do |conn|
|
|
76
|
+
conn.call("DEL", key(id))
|
|
77
|
+
conn.call("SREM", INDEX, id)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def ids
|
|
82
|
+
Sidekiq.redis { |conn| conn.call("SMEMBERS", INDEX) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def key(id) = "roundhouse:snapshot:#{id}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require "roundhouse_ui/version"
|
|
2
|
+
require "roundhouse_ui/engine"
|
|
3
|
+
require "sidekiq/api"
|
|
4
|
+
require "roundhouse_ui/pause"
|
|
5
|
+
require "roundhouse_ui/fetch"
|
|
6
|
+
require "roundhouse_ui/snapshots"
|
|
7
|
+
require "roundhouse_ui/observability"
|
|
8
|
+
require "roundhouse_ui/audit"
|
|
9
|
+
require "roundhouse_ui/redaction"
|
|
10
|
+
require "roundhouse_ui/cancellation"
|
|
11
|
+
require "roundhouse_ui/cancel_middleware"
|
|
12
|
+
require "roundhouse_ui/metrics"
|
|
13
|
+
|
|
14
|
+
# Brand name is "Roundhouse"; the gem and Ruby namespace are RoundhouseUi
|
|
15
|
+
# (matching the published gem name `roundhouse_ui`).
|
|
16
|
+
module RoundhouseUi
|
|
17
|
+
class << self
|
|
18
|
+
# When true, destructive actions (purge, retry, delete, …) are disabled.
|
|
19
|
+
# Mount Roundhouse read-only where operators should only observe.
|
|
20
|
+
attr_accessor :read_only
|
|
21
|
+
|
|
22
|
+
# Pluggable snapshot storage. Defaults to Redis; assign any object that
|
|
23
|
+
# responds to write(id, blob) / read(id) / delete(id) / ids.
|
|
24
|
+
attr_writer :snapshot_store
|
|
25
|
+
|
|
26
|
+
def snapshot_store
|
|
27
|
+
@snapshot_store ||= Snapshots::RedisStore.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Pluggable APM deep-links. Defaults to no links; assign a DatadogAdapter
|
|
31
|
+
# (or your own) to deep-link jobs out to your observability tool.
|
|
32
|
+
attr_writer :observability
|
|
33
|
+
|
|
34
|
+
def observability
|
|
35
|
+
@observability ||= Observability::NullAdapter.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# How the audit log names the person taking an action. Auth is the host's
|
|
39
|
+
# job, so give Roundhouse a callable that pulls the actor from the request:
|
|
40
|
+
#
|
|
41
|
+
# RoundhouseUi.actor_resolver = ->(controller) { controller.current_user&.email }
|
|
42
|
+
#
|
|
43
|
+
# Defaults to "anonymous".
|
|
44
|
+
attr_accessor :actor_resolver
|
|
45
|
+
|
|
46
|
+
# Opt-in: enqueue brand-new jobs and edit/re-enqueue existing ones from the
|
|
47
|
+
# UI. Off by default — it's a sharp tool (bad edits create unrunnable jobs).
|
|
48
|
+
attr_accessor :allow_job_editing
|
|
49
|
+
|
|
50
|
+
# Argument keys (substring, case-insensitive) to mask when displaying jobs.
|
|
51
|
+
# e.g. RoundhouseUi.redact_args = %w[password token secret]. Default: none.
|
|
52
|
+
attr_accessor :redact_args
|
|
53
|
+
|
|
54
|
+
# Configure in an initializer:
|
|
55
|
+
#
|
|
56
|
+
# RoundhouseUi.configure do |c|
|
|
57
|
+
# c.read_only = !Rails.env.development?
|
|
58
|
+
# end
|
|
59
|
+
def configure
|
|
60
|
+
yield self
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Cooperative cancellation check for long-running jobs:
|
|
64
|
+
# raise SomeStop if RoundhouseUi.cancelled?(jid)
|
|
65
|
+
def cancelled?(jid)
|
|
66
|
+
Cancellation.cancelled?(jid)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
self.read_only = false
|
|
71
|
+
self.allow_job_editing = false
|
|
72
|
+
self.redact_args = []
|
|
73
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: roundhouse_ui
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- R.J. Robinson
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rails
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: sidekiq
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '7.0'
|
|
40
|
+
description: 'A mountable Rails engine that replaces the Sidekiq Web UI with a real-time
|
|
41
|
+
control plane: live queues, search, bulk actions, stuck-queue detection, snapshots,
|
|
42
|
+
and pluggable observability.'
|
|
43
|
+
email:
|
|
44
|
+
- rj@trainual.com
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- MIT-LICENSE
|
|
50
|
+
- README.md
|
|
51
|
+
- Rakefile
|
|
52
|
+
- app/assets/javascripts/roundhouse_ui/turbo.min.js
|
|
53
|
+
- app/assets/stylesheets/roundhouse_ui/application.css
|
|
54
|
+
- app/controllers/concerns/roundhouse_ui/job_set_browsing.rb
|
|
55
|
+
- app/controllers/roundhouse_ui/application_controller.rb
|
|
56
|
+
- app/controllers/roundhouse_ui/assets_controller.rb
|
|
57
|
+
- app/controllers/roundhouse_ui/audit_controller.rb
|
|
58
|
+
- app/controllers/roundhouse_ui/busy_controller.rb
|
|
59
|
+
- app/controllers/roundhouse_ui/capsules_controller.rb
|
|
60
|
+
- app/controllers/roundhouse_ui/dashboard_controller.rb
|
|
61
|
+
- app/controllers/roundhouse_ui/dead_controller.rb
|
|
62
|
+
- app/controllers/roundhouse_ui/errors_controller.rb
|
|
63
|
+
- app/controllers/roundhouse_ui/jobs_controller.rb
|
|
64
|
+
- app/controllers/roundhouse_ui/metrics_controller.rb
|
|
65
|
+
- app/controllers/roundhouse_ui/queues_controller.rb
|
|
66
|
+
- app/controllers/roundhouse_ui/redis_controller.rb
|
|
67
|
+
- app/controllers/roundhouse_ui/retries_controller.rb
|
|
68
|
+
- app/controllers/roundhouse_ui/scheduled_controller.rb
|
|
69
|
+
- app/controllers/roundhouse_ui/snapshots_controller.rb
|
|
70
|
+
- app/controllers/roundhouse_ui/workers_controller.rb
|
|
71
|
+
- app/helpers/roundhouse_ui/application_helper.rb
|
|
72
|
+
- app/helpers/roundhouse_ui/nav_helper.rb
|
|
73
|
+
- app/helpers/roundhouse_ui/observability_helper.rb
|
|
74
|
+
- app/views/layouts/roundhouse_ui/application.html.erb
|
|
75
|
+
- app/views/roundhouse_ui/audit/index.html.erb
|
|
76
|
+
- app/views/roundhouse_ui/busy/index.html.erb
|
|
77
|
+
- app/views/roundhouse_ui/capsules/index.html.erb
|
|
78
|
+
- app/views/roundhouse_ui/dashboard/show.html.erb
|
|
79
|
+
- app/views/roundhouse_ui/dead/index.html.erb
|
|
80
|
+
- app/views/roundhouse_ui/errors/index.html.erb
|
|
81
|
+
- app/views/roundhouse_ui/jobs/_form.html.erb
|
|
82
|
+
- app/views/roundhouse_ui/jobs/edit.html.erb
|
|
83
|
+
- app/views/roundhouse_ui/jobs/new.html.erb
|
|
84
|
+
- app/views/roundhouse_ui/jobs/show.html.erb
|
|
85
|
+
- app/views/roundhouse_ui/metrics/show.html.erb
|
|
86
|
+
- app/views/roundhouse_ui/queues/index.html.erb
|
|
87
|
+
- app/views/roundhouse_ui/redis/show.html.erb
|
|
88
|
+
- app/views/roundhouse_ui/retries/index.html.erb
|
|
89
|
+
- app/views/roundhouse_ui/scheduled/index.html.erb
|
|
90
|
+
- app/views/roundhouse_ui/shared/_pager.html.erb
|
|
91
|
+
- app/views/roundhouse_ui/snapshots/index.html.erb
|
|
92
|
+
- app/views/roundhouse_ui/workers/index.html.erb
|
|
93
|
+
- config/routes.rb
|
|
94
|
+
- lib/roundhouse_ui.rb
|
|
95
|
+
- lib/roundhouse_ui/audit.rb
|
|
96
|
+
- lib/roundhouse_ui/cancel_middleware.rb
|
|
97
|
+
- lib/roundhouse_ui/cancellation.rb
|
|
98
|
+
- lib/roundhouse_ui/engine.rb
|
|
99
|
+
- lib/roundhouse_ui/fetch.rb
|
|
100
|
+
- lib/roundhouse_ui/metrics.rb
|
|
101
|
+
- lib/roundhouse_ui/observability.rb
|
|
102
|
+
- lib/roundhouse_ui/pause.rb
|
|
103
|
+
- lib/roundhouse_ui/redaction.rb
|
|
104
|
+
- lib/roundhouse_ui/snapshots.rb
|
|
105
|
+
- lib/roundhouse_ui/version.rb
|
|
106
|
+
- lib/tasks/roundhouse_ui_tasks.rake
|
|
107
|
+
homepage: https://github.com/rjrobinson/roundhouse_ui
|
|
108
|
+
licenses:
|
|
109
|
+
- MIT
|
|
110
|
+
metadata:
|
|
111
|
+
source_code_uri: https://github.com/rjrobinson/roundhouse_ui
|
|
112
|
+
changelog_uri: https://github.com/rjrobinson/roundhouse_ui/blob/main/CHANGELOG.md
|
|
113
|
+
rubygems_mfa_required: 'true'
|
|
114
|
+
rdoc_options: []
|
|
115
|
+
require_paths:
|
|
116
|
+
- lib
|
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
|
+
requirements:
|
|
119
|
+
- - ">="
|
|
120
|
+
- !ruby/object:Gem::Version
|
|
121
|
+
version: '3.1'
|
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - ">="
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '0'
|
|
127
|
+
requirements: []
|
|
128
|
+
rubygems_version: 4.0.10
|
|
129
|
+
specification_version: 4
|
|
130
|
+
summary: Roundhouse — a modern, real-time web UI for Sidekiq.
|
|
131
|
+
test_files: []
|