cosmonats 0.8.0 → 0.9.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 +4 -4
- data/README.md +21 -11
- data/lib/cosmo/api/counter.rb +1 -1
- data/lib/cosmo/api/cron/entry.rb +10 -11
- data/lib/cosmo/api/cron.rb +3 -3
- data/lib/cosmo/api/job.rb +1 -1
- data/lib/cosmo/api/kv.rb +3 -3
- data/lib/cosmo/api/stats/busy.rb +5 -0
- data/lib/cosmo/api/stats/metrics.rb +3 -3
- data/lib/cosmo/api/stats.rb +15 -0
- data/lib/cosmo/api/stream.rb +7 -2
- data/lib/cosmo/client.rb +10 -13
- data/lib/cosmo/job/data.rb +1 -1
- data/lib/cosmo/job/processor.rb +5 -6
- data/lib/cosmo/utils.rb +0 -1
- data/lib/cosmo/version.rb +1 -1
- data/lib/cosmo/web/assets/app.css +271 -629
- data/lib/cosmo/web/assets/app.js +158 -0
- data/lib/cosmo/web/assets/fonts/OFL.txt +92 -0
- data/lib/cosmo/web/assets/fonts/geist-mono.woff2 +0 -0
- data/lib/cosmo/web/assets/fonts/geist.woff2 +0 -0
- data/lib/cosmo/web/assets/logo.svg +10 -0
- data/lib/cosmo/web/cache.rb +75 -0
- data/lib/cosmo/web/chart.rb +62 -38
- data/lib/cosmo/web/circuit.rb +55 -0
- data/lib/cosmo/web/context.rb +0 -4
- data/lib/cosmo/web/controllers/application.rb +16 -0
- data/lib/cosmo/web/controllers/batches.rb +1 -0
- data/lib/cosmo/web/controllers/crons.rb +9 -2
- data/lib/cosmo/web/controllers/jobs.rb +50 -59
- data/lib/cosmo/web/controllers/metrics.rb +1 -0
- data/lib/cosmo/web/controllers/overview.rb +70 -0
- data/lib/cosmo/web/controllers/processes.rb +33 -0
- data/lib/cosmo/web/controllers/streams.rb +26 -28
- data/lib/cosmo/web/helpers/application.rb +57 -0
- data/lib/cosmo/web/renderer.rb +19 -6
- data/lib/cosmo/web/throughput.rb +104 -0
- data/lib/cosmo/web/views/batches/_table.erb +42 -54
- data/lib/cosmo/web/views/batches/index.erb +3 -10
- data/lib/cosmo/web/views/crons/_table.erb +32 -53
- data/lib/cosmo/web/views/crons/index.erb +2 -9
- data/lib/cosmo/web/views/jobs/_args.erb +5 -0
- data/lib/cosmo/web/views/jobs/_busy.erb +25 -121
- data/lib/cosmo/web/views/jobs/_dead.erb +42 -82
- data/lib/cosmo/web/views/jobs/_enqueued.erb +33 -113
- data/lib/cosmo/web/views/jobs/_panel.erb +29 -0
- data/lib/cosmo/web/views/jobs/_queue_row.erb +18 -0
- data/lib/cosmo/web/views/jobs/_queues.erb +20 -0
- data/lib/cosmo/web/views/jobs/_scheduled.erb +20 -54
- data/lib/cosmo/web/views/jobs/index.erb +4 -17
- data/lib/cosmo/web/views/layout.erb +73 -22
- data/lib/cosmo/web/views/metrics/_chart.erb +37 -32
- data/lib/cosmo/web/views/metrics/_panel.erb +3 -3
- data/lib/cosmo/web/views/metrics/_table.erb +24 -40
- data/lib/cosmo/web/views/metrics/index.erb +8 -16
- data/lib/cosmo/web/views/overview/_badges.erb +3 -0
- data/lib/cosmo/web/views/overview/_kpis.erb +19 -0
- data/lib/cosmo/web/views/overview/_running.erb +18 -0
- data/lib/cosmo/web/views/overview/_throughput.erb +50 -0
- data/lib/cosmo/web/views/overview/_workers.erb +25 -0
- data/lib/cosmo/web/views/overview/index.erb +28 -0
- data/lib/cosmo/web/views/processes/_table.erb +67 -0
- data/lib/cosmo/web/views/processes/index.erb +1 -0
- data/lib/cosmo/web/views/shared/_pager.erb +22 -0
- data/lib/cosmo/web/views/shared/unavailable.erb +7 -0
- data/lib/cosmo/web/views/streams/_info.erb +28 -86
- data/lib/cosmo/web/views/streams/_list.erb +7 -0
- data/lib/cosmo/web/views/streams/_pause_banner.erb +8 -16
- data/lib/cosmo/web/views/streams/_stream.erb +52 -0
- data/lib/cosmo/web/views/streams/index.erb +3 -11
- data/lib/cosmo/web/views/streams/info.erb +3 -11
- data/lib/cosmo/web.rb +66 -35
- data/sig/cosmo/api/cron/entry.rbs +2 -1
- data/sig/cosmo/api/stats/busy.rbs +2 -0
- data/sig/cosmo/api/stats/metrics.rbs +1 -1
- data/sig/cosmo/api/stats.rbs +4 -0
- data/sig/cosmo/api/stream.rbs +2 -0
- data/sig/cosmo/client.rbs +1 -0
- metadata +31 -18
- data/lib/cosmo/utils/overrides.rb +0 -206
- data/lib/cosmo/utils/warnings.rb +0 -17
- data/lib/cosmo/web/controllers/actions.rb +0 -16
- data/lib/cosmo/web/views/actions/index.erb +0 -7
- data/lib/cosmo/web/views/jobs/_processes.erb +0 -145
- data/lib/cosmo/web/views/jobs/_stats.erb +0 -77
- data/lib/cosmo/web/views/jobs/_tabs.erb +0 -14
- data/lib/cosmo/web/views/jobs/busy.erb +0 -18
- data/lib/cosmo/web/views/jobs/dead.erb +0 -18
- data/lib/cosmo/web/views/jobs/enqueued.erb +0 -18
- data/lib/cosmo/web/views/jobs/scheduled.erb +0 -18
- data/lib/cosmo/web/views/streams/_stream_row.erb +0 -42
- data/lib/cosmo/web/views/streams/_table.erb +0 -25
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
<% nav = @polling ? { limit: @limit } : { limit: @limit, poll: 0 } -%>
|
|
2
|
-
<% states = { "running" => "badge-success", "quiet" => "badge-warning", "stopping" => "badge-danger" } -%>
|
|
3
|
-
<% kinds = { "jobs" => "Jobs", "streams" => "Streams", "jobs+streams" => "Jobs & Streams", "none" => "No subscriptions" } -%>
|
|
4
|
-
<div id="processes-poller"
|
|
5
|
-
<% if @polling -%>
|
|
6
|
-
hx-get="<%= url_for('/jobs/_processes', page: @page, limit: @limit) %>"
|
|
7
|
-
hx-trigger="every <%= poll_interval %>s"
|
|
8
|
-
hx-swap="outerHTML"
|
|
9
|
-
<% end -%>
|
|
10
|
-
>
|
|
11
|
-
<div class="pending">
|
|
12
|
-
<span></span>
|
|
13
|
-
<span class="poll-status">
|
|
14
|
-
<span class="text-muted"><%= @total %> process(es) alive</span>
|
|
15
|
-
<% if @polling -%>
|
|
16
|
-
<a class="btn btn-sm"
|
|
17
|
-
hx-get="<%= url_for('/jobs/_processes', nav.merge(page: @page, poll: 0)) %>"
|
|
18
|
-
hx-target="#processes-poller"
|
|
19
|
-
hx-swap="outerHTML"
|
|
20
|
-
hx-indicator="#global-spinner">⏹ Stop Polling</a>
|
|
21
|
-
<% else -%>
|
|
22
|
-
<a class="btn btn-sm btn-primary"
|
|
23
|
-
hx-get="<%= url_for('/jobs/_processes', page: @page, limit: @limit) %>"
|
|
24
|
-
hx-target="#processes-poller"
|
|
25
|
-
hx-swap="outerHTML"
|
|
26
|
-
hx-indicator="#global-spinner">▶ Live Poll</a>
|
|
27
|
-
<% end -%>
|
|
28
|
-
</span>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<% if @groups.empty? -%>
|
|
32
|
-
<div class="alert alert-warning">No worker processes are running</div>
|
|
33
|
-
<% else -%>
|
|
34
|
-
<div class="table-container">
|
|
35
|
-
<table>
|
|
36
|
-
<thead>
|
|
37
|
-
<tr>
|
|
38
|
-
<th>Process</th>
|
|
39
|
-
<th>Command</th>
|
|
40
|
-
<th>Subscriptions</th>
|
|
41
|
-
<th>Busy</th>
|
|
42
|
-
<th>State</th>
|
|
43
|
-
<th>RTT</th>
|
|
44
|
-
<th>Reconnects</th>
|
|
45
|
-
<th>Memory</th>
|
|
46
|
-
<th>Uptime</th>
|
|
47
|
-
<th>Last beat</th>
|
|
48
|
-
</tr>
|
|
49
|
-
</thead>
|
|
50
|
-
<tbody>
|
|
51
|
-
<% @groups.each do |kind, group| -%>
|
|
52
|
-
<tr class="group-row">
|
|
53
|
-
<td colspan="10"><%= h(kinds.fetch(kind, kind)) %> <span class="text-muted">(<%= group.size %>)</span></td>
|
|
54
|
-
</tr>
|
|
55
|
-
<% group.each do |process| -%>
|
|
56
|
-
<% nats = Hash(process[:nats]) -%>
|
|
57
|
-
<tr>
|
|
58
|
-
<td>
|
|
59
|
-
<div class="job-class"><%= h(process[:hostname]) %>:<%= h(process[:pid]) %></div>
|
|
60
|
-
<div class="text-muted" style="font-size: var(--font-size-small);">
|
|
61
|
-
<%= h(nats[:ip] || "unknown IP") %>
|
|
62
|
-
<% if nats[:name] -%>· <code><%= h(nats[:name]) %></code><% end -%>
|
|
63
|
-
</div>
|
|
64
|
-
</td>
|
|
65
|
-
<td>
|
|
66
|
-
<% cmdline = process[:cmdline].to_s -%>
|
|
67
|
-
<div class="job-id">
|
|
68
|
-
<% if cmdline.length > 32 -%>
|
|
69
|
-
<details>
|
|
70
|
-
<summary>
|
|
71
|
-
<code class="truncate" title="<%= h(cmdline) %>"><%= h(cmdline) %></code>
|
|
72
|
-
</summary>
|
|
73
|
-
<code style="font-size: var(--font-size-small);"><%= h(cmdline) %></code>
|
|
74
|
-
</details>
|
|
75
|
-
<% else -%>
|
|
76
|
-
<code style="font-size: var(--font-size-small);"><%= h(cmdline) %></code>
|
|
77
|
-
<% end -%>
|
|
78
|
-
<div class="text-muted" style="font-size: var(--font-size-small);">
|
|
79
|
-
cosmo <%= h(process[:version]) %> · <%= h(process[:ruby]) %>
|
|
80
|
-
<% if process[:http_port] -%>· http :<%= h(process[:http_port]) %><% end -%>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
</td>
|
|
84
|
-
<td>
|
|
85
|
-
<% Hash(process[:subscriptions]).each do |type, names| -%>
|
|
86
|
-
<% next if Array(names).empty? -%>
|
|
87
|
-
<div>
|
|
88
|
-
<% if kind == "jobs+streams" -%><span class="text-muted"><%= h(type) %>:</span><% end -%>
|
|
89
|
-
<code><%= h(Array(names).join(", ")) %></code>
|
|
90
|
-
</div>
|
|
91
|
-
<% end -%>
|
|
92
|
-
</td>
|
|
93
|
-
<td><%= h(process[:busy]) %> / <%= h(process[:concurrency]) %></td>
|
|
94
|
-
<td><span class="badge <%= states.fetch(process[:state].to_s, 'badge-info') %>"><%= h(process[:state]) %></span></td>
|
|
95
|
-
<td><%= nats[:rtt] ? "#{h(nats[:rtt])}ms" : '—' %></td>
|
|
96
|
-
<td><%= h(nats[:reconnects].to_i) %></td>
|
|
97
|
-
<td><%= process[:rss] ? format_bytes(process[:rss].to_i * 1024) : '—' %></td>
|
|
98
|
-
<td><%= elapsed(process[:started_at]) %></td>
|
|
99
|
-
<td><%= elapsed(process[:beat_at]) %> ago</td>
|
|
100
|
-
</tr>
|
|
101
|
-
<% end -%>
|
|
102
|
-
<% end -%>
|
|
103
|
-
</tbody>
|
|
104
|
-
</table>
|
|
105
|
-
</div>
|
|
106
|
-
<% end -%>
|
|
107
|
-
|
|
108
|
-
<% if @total_pages.to_i > 1 -%>
|
|
109
|
-
<div class="pagination">
|
|
110
|
-
<% if @page > 1 -%>
|
|
111
|
-
<a hx-get="<%= url_for('/jobs/_processes', nav.merge(page: @page - 1)) %>"
|
|
112
|
-
hx-target="#processes-poller"
|
|
113
|
-
hx-swap="outerHTML"
|
|
114
|
-
hx-indicator="#global-spinner"
|
|
115
|
-
class="btn">← Prev</a>
|
|
116
|
-
<% else -%>
|
|
117
|
-
<span class="btn btn-disabled">← Prev</span>
|
|
118
|
-
<% end -%>
|
|
119
|
-
|
|
120
|
-
<% pages(@page, @total_pages).each do |p| -%>
|
|
121
|
-
<% if p == :gap -%>
|
|
122
|
-
<span class="pagination-gap">…</span>
|
|
123
|
-
<% elsif p == @page -%>
|
|
124
|
-
<span class="btn btn-primary btn-disabled"><%= p %></span>
|
|
125
|
-
<% else -%>
|
|
126
|
-
<a hx-get="<%= url_for('/jobs/_processes', nav.merge(page: p)) %>"
|
|
127
|
-
hx-target="#processes-poller"
|
|
128
|
-
hx-swap="outerHTML"
|
|
129
|
-
hx-indicator="#global-spinner"
|
|
130
|
-
class="btn"><%= p %></a>
|
|
131
|
-
<% end -%>
|
|
132
|
-
<% end -%>
|
|
133
|
-
|
|
134
|
-
<% if @page < @total_pages -%>
|
|
135
|
-
<a hx-get="<%= url_for('/jobs/_processes', nav.merge(page: @page + 1)) %>"
|
|
136
|
-
hx-target="#processes-poller"
|
|
137
|
-
hx-swap="outerHTML"
|
|
138
|
-
hx-indicator="#global-spinner"
|
|
139
|
-
class="btn">Next →</a>
|
|
140
|
-
<% else -%>
|
|
141
|
-
<span class="btn btn-disabled">Next →</span>
|
|
142
|
-
<% end -%>
|
|
143
|
-
</div>
|
|
144
|
-
<% end -%>
|
|
145
|
-
</div>
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
<div class="cards-container">
|
|
2
|
-
<article class="stat-card">
|
|
3
|
-
<div class="row">
|
|
4
|
-
<p>💪 Processed</p>
|
|
5
|
-
<h4><%= format_numbers(@processed) %></h4>
|
|
6
|
-
</div>
|
|
7
|
-
<div class="row">
|
|
8
|
-
<p>😥 Failed</p>
|
|
9
|
-
<h4><%= format_numbers(@failed) %></h4>
|
|
10
|
-
</div>
|
|
11
|
-
<div class="row">
|
|
12
|
-
<p>🔄 Retries</p>
|
|
13
|
-
<h4><%= format_numbers(@retries) %></h4>
|
|
14
|
-
</div>
|
|
15
|
-
</article>
|
|
16
|
-
<article class="stat-card">
|
|
17
|
-
<h3><%= format_numbers(@busy) %></h3>
|
|
18
|
-
<p>
|
|
19
|
-
<a href="<%= url_for('/jobs/busy') %>"
|
|
20
|
-
hx-get="<%= url_for('/jobs/busy') %>"
|
|
21
|
-
hx-target="#content"
|
|
22
|
-
hx-push-url="true"
|
|
23
|
-
hx-indicator="#global-spinner">⏳ Busy</a>
|
|
24
|
-
</p>
|
|
25
|
-
</article>
|
|
26
|
-
<article class="stat-card">
|
|
27
|
-
<h3><%= format_numbers(@enqueued) %></h3>
|
|
28
|
-
<p>
|
|
29
|
-
<a href="<%= url_for('/jobs/enqueued') %>"
|
|
30
|
-
hx-get="<%= url_for('/jobs/enqueued') %>"
|
|
31
|
-
hx-target="#content"
|
|
32
|
-
hx-push-url="true"
|
|
33
|
-
hx-indicator="#global-spinner"
|
|
34
|
-
class="<%= 'active' if referrer?('/jobs/enqueued') %>">📬 Enqueued</a>
|
|
35
|
-
</p>
|
|
36
|
-
</article>
|
|
37
|
-
<% if Cosmo::Config.scheduled.enabled -%>
|
|
38
|
-
<article class="stat-card">
|
|
39
|
-
<h3><%= format_numbers(@scheduled) %></h3>
|
|
40
|
-
<p>
|
|
41
|
-
<a href="<%= url_for('/jobs/scheduled') %>"
|
|
42
|
-
hx-get="<%= url_for('/jobs/scheduled') %>"
|
|
43
|
-
hx-target="#content"
|
|
44
|
-
hx-push-url="true"
|
|
45
|
-
hx-indicator="#global-spinner"
|
|
46
|
-
class="<%= 'active' if referrer?('/jobs/scheduled') %>">⏰ Scheduled</a>
|
|
47
|
-
</p>
|
|
48
|
-
</article>
|
|
49
|
-
<% end -%>
|
|
50
|
-
<% if Cosmo::Config.dead.enabled -%>
|
|
51
|
-
<article class="stat-card">
|
|
52
|
-
<h3><%= format_numbers(@dead) %></h3>
|
|
53
|
-
<p>
|
|
54
|
-
<a href="<%= url_for('/jobs/dead') %>"
|
|
55
|
-
hx-get="<%= url_for('/jobs/dead') %>"
|
|
56
|
-
hx-target="#content"
|
|
57
|
-
hx-push-url="true"
|
|
58
|
-
hx-indicator="#global-spinner"
|
|
59
|
-
class="<%= 'active' if referrer?('/jobs/dead') %>">💀 Dead</a>
|
|
60
|
-
</p>
|
|
61
|
-
</article>
|
|
62
|
-
<% end -%>
|
|
63
|
-
</div>
|
|
64
|
-
|
|
65
|
-
<script>
|
|
66
|
-
(function () {
|
|
67
|
-
const links = document.querySelectorAll('.cards-container a');
|
|
68
|
-
|
|
69
|
-
links.forEach(link => {
|
|
70
|
-
link.addEventListener('click', () => {
|
|
71
|
-
links.forEach(item => item.classList.remove('active'));
|
|
72
|
-
|
|
73
|
-
link.classList.add('active');
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
})();
|
|
77
|
-
</script>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<nav class="tabs">
|
|
2
|
-
<a href="<%= url_for('/jobs') %>"
|
|
3
|
-
class="<%= 'active' if path_prefix?('/jobs') %>">📋 Dashboard</a>
|
|
4
|
-
<a href="<%= url_for('/batches') %>"
|
|
5
|
-
class="<%= 'active' if path_prefix?('/batches') %>">📦 Batches</a>
|
|
6
|
-
<% if Cosmo::Config.scheduled.enabled -%>
|
|
7
|
-
<a href="<%= url_for('/crons') %>"
|
|
8
|
-
class="<%= 'active' if path_prefix?('/crons') %>">⏰ Crons</a>
|
|
9
|
-
<% end -%>
|
|
10
|
-
<% if Cosmo::Config.metrics.enabled -%>
|
|
11
|
-
<a href="<%= url_for('/metrics') %>"
|
|
12
|
-
class="<%= 'active' if path_prefix?('/metrics') %>">📊 Metrics</a>
|
|
13
|
-
<% end -%>
|
|
14
|
-
</nav>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<section>
|
|
2
|
-
<header><%= render('jobs/_tabs') %></header>
|
|
3
|
-
|
|
4
|
-
<div hx-get="<%= url_for('/jobs/_stats') %>"
|
|
5
|
-
hx-trigger="load, every <%= poll_interval %>s"
|
|
6
|
-
hx-swap="innerHTML">
|
|
7
|
-
<div class="alert alert-info">Loading statistics…</div>
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
<div id="content">
|
|
11
|
-
<div id="busy-poller"
|
|
12
|
-
hx-get="<%= url_for('/jobs/_busy') %>"
|
|
13
|
-
hx-trigger="load"
|
|
14
|
-
hx-swap="outerHTML">
|
|
15
|
-
<div class="alert alert-info">Loading busy jobs…</div>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
</section>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<section>
|
|
2
|
-
<header><%= render('jobs/_tabs') %></header>
|
|
3
|
-
|
|
4
|
-
<div hx-get="<%= url_for('/jobs/_stats') %>"
|
|
5
|
-
hx-trigger="load, every <%= poll_interval %>s"
|
|
6
|
-
hx-swap="innerHTML">
|
|
7
|
-
<div class="alert alert-info">Loading statistics…</div>
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
<div id="content">
|
|
11
|
-
<div id="dead-jobs"
|
|
12
|
-
hx-get="<%= url_for('/jobs/_dead') %>"
|
|
13
|
-
hx-trigger="load"
|
|
14
|
-
hx-swap="outerHTML">
|
|
15
|
-
<div class="alert alert-info">Loading dead jobs…</div>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
</section>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<section>
|
|
2
|
-
<header><%= render('jobs/_tabs') %></header>
|
|
3
|
-
|
|
4
|
-
<div hx-get="<%= url_for('/jobs/_stats') %>"
|
|
5
|
-
hx-trigger="load, every <%= poll_interval %>s"
|
|
6
|
-
hx-swap="innerHTML">
|
|
7
|
-
<div class="alert alert-info">Loading statistics…</div>
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
<div id="content">
|
|
11
|
-
<div id="enqueued-poller"
|
|
12
|
-
hx-get="<%= url_for('/jobs/_enqueued', stream_name: @stream_name) %>"
|
|
13
|
-
hx-trigger="load"
|
|
14
|
-
hx-swap="outerHTML">
|
|
15
|
-
<div class="alert alert-info">Loading enqueued jobs…</div>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
</section>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<section>
|
|
2
|
-
<header><%= render('jobs/_tabs') %></header>
|
|
3
|
-
|
|
4
|
-
<div hx-get="<%= url_for('/jobs/_stats') %>"
|
|
5
|
-
hx-trigger="load, every <%= poll_interval %>s"
|
|
6
|
-
hx-swap="innerHTML">
|
|
7
|
-
<div class="alert alert-info">Loading statistics…</div>
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
<div id="content">
|
|
11
|
-
<div id="scheduled-poller"
|
|
12
|
-
hx-get="<%= url_for('/jobs/_scheduled') %>"
|
|
13
|
-
hx-trigger="load"
|
|
14
|
-
hx-swap="outerHTML">
|
|
15
|
-
<div class="alert alert-info">Loading scheduled jobs…</div>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
</section>
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
<tr id="stream-row-<%= h(@stream[:name]) %>">
|
|
2
|
-
<td>
|
|
3
|
-
<a href="<%= url_for('/streams/info', { name: u(@stream[:name]) }) %>"
|
|
4
|
-
hx-get="<%= url_for('/streams/info', { name: u(@stream[:name]) }) %>"
|
|
5
|
-
hx-target="#content"
|
|
6
|
-
hx-push-url="true"
|
|
7
|
-
class="stream-link"><%= h(@stream[:name]) %></a>
|
|
8
|
-
</td>
|
|
9
|
-
<td><%= format_numbers(@stream[:messages]) %></td>
|
|
10
|
-
<td><%= format_bytes(@stream[:bytes]) %></td>
|
|
11
|
-
<td><%= @stream[:consumer_count] %></td>
|
|
12
|
-
<td>
|
|
13
|
-
<div class="subjects">
|
|
14
|
-
<% Array(@stream[:subjects]).each do |subject| -%>
|
|
15
|
-
<span class="subject-tag"><%= h(subject) %></span>
|
|
16
|
-
<% end -%>
|
|
17
|
-
</div>
|
|
18
|
-
</td>
|
|
19
|
-
<td><code><%= format_numbers(@stream[:first_seq]) %> → <%= format_numbers(@stream[:last_seq]) %></code></td>
|
|
20
|
-
<td>
|
|
21
|
-
<% if @stream[:paused] -%>
|
|
22
|
-
<span class="badge badge-warning">⏸ Paused</span>
|
|
23
|
-
<% elsif @stream[:consumer_count].to_i > 0 -%>
|
|
24
|
-
<span class="badge badge-success">▶ Active</span>
|
|
25
|
-
<% else -%>
|
|
26
|
-
<span class="badge">No consumers</span>
|
|
27
|
-
<% end -%>
|
|
28
|
-
</td>
|
|
29
|
-
<td>
|
|
30
|
-
<% if @stream[:paused] -%>
|
|
31
|
-
<a hx-patch="<%= url_for('/streams/unpause', { name: u(@stream[:name]) }) %>"
|
|
32
|
-
hx-target="#stream-row-<%= h(@stream[:name]) %>"
|
|
33
|
-
hx-swap="outerHTML"
|
|
34
|
-
class="btn btn-success">▶ Resume</a>
|
|
35
|
-
<% else -%>
|
|
36
|
-
<a hx-patch="<%= url_for('/streams/pause', { name: u(@stream[:name]) }) %>"
|
|
37
|
-
hx-target="#stream-row-<%= h(@stream[:name]) %>"
|
|
38
|
-
hx-swap="outerHTML"
|
|
39
|
-
class="btn btn-warning">⏸ Pause</a>
|
|
40
|
-
<% end -%>
|
|
41
|
-
</td>
|
|
42
|
-
</tr>
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<% if @streams.empty? -%>
|
|
2
|
-
<div class="alert alert-info">No streams found</div>
|
|
3
|
-
<% else -%>
|
|
4
|
-
<div class="table-container">
|
|
5
|
-
<table>
|
|
6
|
-
<thead>
|
|
7
|
-
<tr>
|
|
8
|
-
<th>Name</th>
|
|
9
|
-
<th>Messages</th>
|
|
10
|
-
<th>Size</th>
|
|
11
|
-
<th>Consumers</th>
|
|
12
|
-
<th>Subjects</th>
|
|
13
|
-
<th>Sequence</th>
|
|
14
|
-
<th>Status</th>
|
|
15
|
-
<th>Actions</th>
|
|
16
|
-
</tr>
|
|
17
|
-
</thead>
|
|
18
|
-
<tbody>
|
|
19
|
-
<% @streams.each do |stream| -%>
|
|
20
|
-
<%= render("streams/_stream_row", { stream: stream }) %>
|
|
21
|
-
<% end -%>
|
|
22
|
-
</tbody>
|
|
23
|
-
</table>
|
|
24
|
-
</div>
|
|
25
|
-
<% end -%>
|