sktop 0.1.5 → 0.1.6
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/lib/sktop/cli.rb +125 -6
- data/lib/sktop/display.rb +189 -25
- data/lib/sktop/job_actions.rb +9 -0
- data/lib/sktop/stats_collector.rb +13 -0
- data/lib/sktop/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 72e27a287d42246bf03393f3f5d8fd83fcf2dcb52d3c32a242f6631a556d5a90
|
|
4
|
+
data.tar.gz: a26fa56421cf3fa038f2d7fa7ec86e204189be4bd21419d1ddf896631f59a8cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d7aa57eac65085688adadc80a4d587c6c3e0c100c09518675bf4cc65fdcfac93e37e404a7476eda3a4b4ec2d2b7a595f3e6231a2b1c414475c4907fd52ff4275
|
|
7
|
+
data.tar.gz: ef09ee20ae517a01e85c427bc291d8adff140e0239342336f22365df774efdf83c0df76b34839ed99e15d63a66c36de4eaeb4f7634a24d098c27fab6894055ec
|
data/lib/sktop/cli.rb
CHANGED
|
@@ -195,7 +195,17 @@ module Sktop
|
|
|
195
195
|
scheduled_jobs: collector.scheduled_jobs(limit: 500),
|
|
196
196
|
dead_jobs: collector.dead_jobs(limit: 500)
|
|
197
197
|
}
|
|
198
|
+
|
|
199
|
+
# If viewing queue jobs, refresh that data too
|
|
200
|
+
if @display.current_view == :queue_jobs && @display.selected_queue
|
|
201
|
+
snapshot[:queue_jobs] = collector.queue_jobs(@display.selected_queue, limit: 500)
|
|
202
|
+
end
|
|
203
|
+
|
|
198
204
|
@data_mutex.synchronize do
|
|
205
|
+
# Preserve queue_jobs if not refreshed above but still in that view
|
|
206
|
+
if @cached_data && @cached_data[:queue_jobs] && !snapshot[:queue_jobs]
|
|
207
|
+
snapshot[:queue_jobs] = @cached_data[:queue_jobs]
|
|
208
|
+
end
|
|
199
209
|
@cached_data = snapshot
|
|
200
210
|
@data_version += 1
|
|
201
211
|
end
|
|
@@ -282,6 +292,8 @@ module Sktop
|
|
|
282
292
|
@display.current_view = :dead
|
|
283
293
|
when 'm', 'M'
|
|
284
294
|
@display.current_view = :main
|
|
295
|
+
when "\r", "\n" # Enter key
|
|
296
|
+
handle_enter_action
|
|
285
297
|
when "\x12" # Ctrl+R - retry job
|
|
286
298
|
handle_retry_action
|
|
287
299
|
when "\x18" # Ctrl+X - delete job
|
|
@@ -299,8 +311,10 @@ module Sktop
|
|
|
299
311
|
@display.select_up
|
|
300
312
|
when "[B" # Down arrow
|
|
301
313
|
@display.select_down
|
|
302
|
-
when "[C" # Right arrow
|
|
303
|
-
|
|
314
|
+
when "[C" # Right arrow - next view
|
|
315
|
+
@display.next_view
|
|
316
|
+
when "[D" # Left arrow - previous view
|
|
317
|
+
@display.previous_view
|
|
304
318
|
when "[5~" # Page Up
|
|
305
319
|
@display.page_up
|
|
306
320
|
when "[6~" # Page Down
|
|
@@ -310,12 +324,12 @@ module Sktop
|
|
|
310
324
|
when "x", "X" # Alt+X - Delete All
|
|
311
325
|
handle_delete_all_action
|
|
312
326
|
else
|
|
313
|
-
# Just Escape key - go to main
|
|
314
|
-
|
|
327
|
+
# Just Escape key - go back or to main
|
|
328
|
+
handle_escape_action
|
|
315
329
|
end
|
|
316
330
|
else
|
|
317
|
-
# Just Escape key - go to main
|
|
318
|
-
|
|
331
|
+
# Just Escape key - go back or to main
|
|
332
|
+
handle_escape_action
|
|
319
333
|
end
|
|
320
334
|
when "\u0003" # Ctrl+C
|
|
321
335
|
raise Interrupt
|
|
@@ -362,6 +376,12 @@ module Sktop
|
|
|
362
376
|
end
|
|
363
377
|
|
|
364
378
|
def handle_delete_action
|
|
379
|
+
# Handle queue_jobs view separately
|
|
380
|
+
if @display.current_view == :queue_jobs
|
|
381
|
+
handle_delete_queue_job_action
|
|
382
|
+
return
|
|
383
|
+
end
|
|
384
|
+
|
|
365
385
|
return unless [:retries, :dead].include?(@display.current_view)
|
|
366
386
|
|
|
367
387
|
data = @data_mutex.synchronize { @cached_data }
|
|
@@ -500,5 +520,104 @@ module Sktop
|
|
|
500
520
|
end
|
|
501
521
|
end
|
|
502
522
|
|
|
523
|
+
def handle_enter_action
|
|
524
|
+
return unless @display.current_view == :queues
|
|
525
|
+
|
|
526
|
+
data = @data_mutex.synchronize { @cached_data }
|
|
527
|
+
unless data
|
|
528
|
+
@display.set_status("No data available")
|
|
529
|
+
return
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
queues = data[:queues]
|
|
533
|
+
selected_idx = @display.selected_index
|
|
534
|
+
|
|
535
|
+
if queues.empty?
|
|
536
|
+
@display.set_status("No queues")
|
|
537
|
+
return
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
if selected_idx >= queues.length
|
|
541
|
+
@display.set_status("Invalid selection")
|
|
542
|
+
return
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
queue = queues[selected_idx]
|
|
546
|
+
queue_name = queue[:name]
|
|
547
|
+
|
|
548
|
+
# Fetch jobs from the queue
|
|
549
|
+
begin
|
|
550
|
+
collector = StatsCollector.new
|
|
551
|
+
jobs = collector.queue_jobs(queue_name, limit: 500)
|
|
552
|
+
|
|
553
|
+
# Update cached data with queue jobs
|
|
554
|
+
@data_mutex.synchronize do
|
|
555
|
+
@cached_data[:queue_jobs] = jobs
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
@display.selected_queue = queue_name
|
|
559
|
+
@display.current_view = :queue_jobs
|
|
560
|
+
@display.set_status("Loaded #{jobs.length} jobs from #{queue_name}")
|
|
561
|
+
rescue => e
|
|
562
|
+
@display.set_status("Error loading queue: #{e.message}")
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
def handle_escape_action
|
|
567
|
+
if @display.current_view == :queue_jobs
|
|
568
|
+
# Go back to queues view
|
|
569
|
+
@display.current_view = :queues
|
|
570
|
+
@display.selected_queue = nil
|
|
571
|
+
else
|
|
572
|
+
# Go to main view
|
|
573
|
+
@display.current_view = :main
|
|
574
|
+
end
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
def handle_delete_queue_job_action
|
|
578
|
+
return unless @display.current_view == :queue_jobs
|
|
579
|
+
|
|
580
|
+
data = @data_mutex.synchronize { @cached_data }
|
|
581
|
+
unless data
|
|
582
|
+
@display.set_status("No data available")
|
|
583
|
+
return
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
jobs = data[:queue_jobs] || []
|
|
587
|
+
selected_idx = @display.selected_index
|
|
588
|
+
queue_name = @display.selected_queue
|
|
589
|
+
|
|
590
|
+
if jobs.empty?
|
|
591
|
+
@display.set_status("No jobs to delete")
|
|
592
|
+
return
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
if selected_idx >= jobs.length
|
|
596
|
+
@display.set_status("Invalid selection")
|
|
597
|
+
return
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
job = jobs[selected_idx]
|
|
601
|
+
unless job[:jid]
|
|
602
|
+
@display.set_status("Job has no JID")
|
|
603
|
+
return
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
begin
|
|
607
|
+
Sktop::JobActions.delete_queue_job(queue_name, job[:jid])
|
|
608
|
+
@display.set_status("Deleted #{job[:class]}")
|
|
609
|
+
|
|
610
|
+
# Refresh the queue jobs
|
|
611
|
+
collector = StatsCollector.new
|
|
612
|
+
new_jobs = collector.queue_jobs(queue_name, limit: 500)
|
|
613
|
+
@data_mutex.synchronize do
|
|
614
|
+
@cached_data[:queue_jobs] = new_jobs
|
|
615
|
+
end
|
|
616
|
+
@rendered_version = -1
|
|
617
|
+
rescue => e
|
|
618
|
+
@display.set_status("Error: #{e.message}")
|
|
619
|
+
end
|
|
620
|
+
end
|
|
621
|
+
|
|
503
622
|
end
|
|
504
623
|
end
|
data/lib/sktop/display.rb
CHANGED
|
@@ -15,8 +15,11 @@ module Sktop
|
|
|
15
15
|
@status_time = nil
|
|
16
16
|
@connection_status = :connecting # :connecting, :connected, :updating, :error
|
|
17
17
|
@last_update = nil
|
|
18
|
+
@selected_queue = nil # Track which queue is being viewed in queue_jobs view
|
|
18
19
|
end
|
|
19
20
|
|
|
21
|
+
attr_accessor :selected_queue
|
|
22
|
+
|
|
20
23
|
def scroll_up
|
|
21
24
|
@scroll_offsets[@current_view] = [@scroll_offsets[@current_view] - 1, 0].max
|
|
22
25
|
end
|
|
@@ -42,7 +45,7 @@ module Sktop
|
|
|
42
45
|
end
|
|
43
46
|
|
|
44
47
|
def selectable_view?
|
|
45
|
-
[:processes, :retries, :dead].include?(@current_view)
|
|
48
|
+
[:queues, :queue_jobs, :processes, :retries, :dead].include?(@current_view)
|
|
46
49
|
end
|
|
47
50
|
|
|
48
51
|
def page_up(page_size = nil)
|
|
@@ -86,6 +89,18 @@ module Sktop
|
|
|
86
89
|
# Don't reset scroll when switching views - preserve position
|
|
87
90
|
end
|
|
88
91
|
|
|
92
|
+
VIEW_ORDER = [:main, :queues, :processes, :workers, :retries, :scheduled, :dead].freeze
|
|
93
|
+
|
|
94
|
+
def next_view
|
|
95
|
+
current_idx = VIEW_ORDER.index(@current_view) || 0
|
|
96
|
+
@current_view = VIEW_ORDER[(current_idx + 1) % VIEW_ORDER.length]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def previous_view
|
|
100
|
+
current_idx = VIEW_ORDER.index(@current_view) || 0
|
|
101
|
+
@current_view = VIEW_ORDER[(current_idx - 1) % VIEW_ORDER.length]
|
|
102
|
+
end
|
|
103
|
+
|
|
89
104
|
def reset_cursor
|
|
90
105
|
print @cursor.move_to(0, 0)
|
|
91
106
|
print @cursor.hide
|
|
@@ -167,6 +182,10 @@ module Sktop
|
|
|
167
182
|
def dead_jobs(limit: 50)
|
|
168
183
|
@data[:dead_jobs]&.first(limit) || []
|
|
169
184
|
end
|
|
185
|
+
|
|
186
|
+
def queue_jobs_cache
|
|
187
|
+
@data[:queue_jobs] || []
|
|
188
|
+
end
|
|
170
189
|
end
|
|
171
190
|
|
|
172
191
|
private
|
|
@@ -175,6 +194,8 @@ module Sktop
|
|
|
175
194
|
case @current_view
|
|
176
195
|
when :queues
|
|
177
196
|
build_queues_detail(collector)
|
|
197
|
+
when :queue_jobs
|
|
198
|
+
build_queue_jobs_detail(collector)
|
|
178
199
|
when :processes
|
|
179
200
|
build_processes_detail(collector)
|
|
180
201
|
when :workers
|
|
@@ -245,7 +266,18 @@ module Sktop
|
|
|
245
266
|
lines << ""
|
|
246
267
|
# Calculate available rows: height - header(1) - blank(1) - section(1) - table_header(1) - footer(1) = height - 5
|
|
247
268
|
max_rows = terminal_height - 5
|
|
248
|
-
|
|
269
|
+
queues_selectable(collector.queues, max_rows).each_line(chomp: true) { |l| lines << l }
|
|
270
|
+
lines << :footer
|
|
271
|
+
lines
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def build_queue_jobs_detail(collector)
|
|
275
|
+
lines = []
|
|
276
|
+
lines << header_bar
|
|
277
|
+
lines << ""
|
|
278
|
+
max_rows = terminal_height - 5
|
|
279
|
+
jobs = collector.respond_to?(:queue_jobs_cache) ? collector.queue_jobs_cache : []
|
|
280
|
+
queue_jobs_selectable(jobs, max_rows).each_line(chomp: true) { |l| lines << l }
|
|
249
281
|
lines << :footer
|
|
250
282
|
lines
|
|
251
283
|
end
|
|
@@ -601,6 +633,133 @@ module Sktop
|
|
|
601
633
|
lines.join("\n")
|
|
602
634
|
end
|
|
603
635
|
|
|
636
|
+
# Selectable queues view - press Enter to view queue contents
|
|
637
|
+
def queues_selectable(queues, max_rows)
|
|
638
|
+
width = terminal_width
|
|
639
|
+
lines = []
|
|
640
|
+
|
|
641
|
+
scroll_offset = @scroll_offsets[@current_view]
|
|
642
|
+
data_rows = max_rows - 3 # Account for section bar, header, and status line
|
|
643
|
+
max_scroll = [queues.length - data_rows, 0].max
|
|
644
|
+
scroll_offset = [[scroll_offset, 0].max, max_scroll].min
|
|
645
|
+
@scroll_offsets[@current_view] = scroll_offset
|
|
646
|
+
|
|
647
|
+
# Clamp selected index
|
|
648
|
+
@selected_index[@current_view] = [[@selected_index[@current_view], 0].max, [queues.length - 1, 0].max].min
|
|
649
|
+
|
|
650
|
+
# Auto-scroll to keep selection visible
|
|
651
|
+
selected = @selected_index[@current_view]
|
|
652
|
+
if selected < scroll_offset
|
|
653
|
+
scroll_offset = selected
|
|
654
|
+
@scroll_offsets[@current_view] = scroll_offset
|
|
655
|
+
elsif selected >= scroll_offset + data_rows
|
|
656
|
+
scroll_offset = selected - data_rows + 1
|
|
657
|
+
@scroll_offsets[@current_view] = scroll_offset
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
scroll_indicator = queues.length > data_rows ? " [#{scroll_offset + 1}-#{[scroll_offset + data_rows, queues.length].min}/#{queues.length}]" : ""
|
|
661
|
+
lines << section_bar("Queues#{scroll_indicator} - ↑↓ select, Enter=view jobs, m=main")
|
|
662
|
+
|
|
663
|
+
if queues.empty?
|
|
664
|
+
lines << @pastel.dim(" No queues")
|
|
665
|
+
return lines.join("\n")
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
name_width = [40, width - 40].max
|
|
669
|
+
header = sprintf(" %-#{name_width}s %10s %10s %10s", "NAME", "SIZE", "LATENCY", "STATUS")
|
|
670
|
+
lines << format_table_header(header)
|
|
671
|
+
|
|
672
|
+
queues.drop(scroll_offset).first(data_rows).each_with_index do |queue, idx|
|
|
673
|
+
actual_idx = scroll_offset + idx
|
|
674
|
+
row = format_queue_row(queue, name_width)
|
|
675
|
+
|
|
676
|
+
if actual_idx == selected
|
|
677
|
+
lines << @pastel.black.on_white(row + " " * [width - visible_string_length(row), 0].max)
|
|
678
|
+
else
|
|
679
|
+
lines << row
|
|
680
|
+
end
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
remaining = queues.length - scroll_offset - data_rows
|
|
684
|
+
if remaining > 0
|
|
685
|
+
lines << @pastel.dim(" ↓ #{remaining} more")
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
# Status message
|
|
689
|
+
if @status_message && @status_time && (Time.now - @status_time) < 3
|
|
690
|
+
lines << @pastel.green(" #{@status_message}")
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
lines.join("\n")
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
# Selectable queue jobs view - press Ctrl+X to delete job
|
|
697
|
+
def queue_jobs_selectable(jobs, max_rows)
|
|
698
|
+
width = terminal_width
|
|
699
|
+
lines = []
|
|
700
|
+
|
|
701
|
+
scroll_offset = @scroll_offsets[@current_view]
|
|
702
|
+
data_rows = max_rows - 3 # Account for section bar, header, and status line
|
|
703
|
+
max_scroll = [jobs.length - data_rows, 0].max
|
|
704
|
+
scroll_offset = [[scroll_offset, 0].max, max_scroll].min
|
|
705
|
+
@scroll_offsets[@current_view] = scroll_offset
|
|
706
|
+
|
|
707
|
+
# Clamp selected index
|
|
708
|
+
@selected_index[@current_view] = [[@selected_index[@current_view], 0].max, [jobs.length - 1, 0].max].min
|
|
709
|
+
|
|
710
|
+
# Auto-scroll to keep selection visible
|
|
711
|
+
selected = @selected_index[@current_view]
|
|
712
|
+
if selected < scroll_offset
|
|
713
|
+
scroll_offset = selected
|
|
714
|
+
@scroll_offsets[@current_view] = scroll_offset
|
|
715
|
+
elsif selected >= scroll_offset + data_rows
|
|
716
|
+
scroll_offset = selected - data_rows + 1
|
|
717
|
+
@scroll_offsets[@current_view] = scroll_offset
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
queue_name = @selected_queue || "unknown"
|
|
721
|
+
scroll_indicator = jobs.length > data_rows ? " [#{scroll_offset + 1}-#{[scroll_offset + data_rows, jobs.length].min}/#{jobs.length}]" : ""
|
|
722
|
+
lines << section_bar("Queue: #{queue_name}#{scroll_indicator} - ↑↓ select, ^X=delete, Esc=back")
|
|
723
|
+
|
|
724
|
+
if jobs.empty?
|
|
725
|
+
lines << @pastel.dim(" No jobs in queue")
|
|
726
|
+
return lines.join("\n")
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
job_width = [35, (width - 50) / 2].max
|
|
730
|
+
args_width = [35, (width - 50) / 2].max
|
|
731
|
+
|
|
732
|
+
header = sprintf(" %-#{job_width}s %-20s %-#{args_width}s", "JOB", "ENQUEUED", "ARGS")
|
|
733
|
+
lines << format_table_header(header)
|
|
734
|
+
|
|
735
|
+
jobs.drop(scroll_offset).first(data_rows).each_with_index do |job, idx|
|
|
736
|
+
actual_idx = scroll_offset + idx
|
|
737
|
+
klass = truncate(job[:class].to_s, job_width)
|
|
738
|
+
enqueued = job[:enqueued_at]&.strftime("%Y-%m-%d %H:%M:%S") || "N/A"
|
|
739
|
+
args = truncate(job[:args].inspect, args_width)
|
|
740
|
+
|
|
741
|
+
row = sprintf(" %-#{job_width}s %-20s %-#{args_width}s", klass, enqueued, args)
|
|
742
|
+
|
|
743
|
+
if actual_idx == selected
|
|
744
|
+
lines << @pastel.black.on_white(row + " " * [width - visible_string_length(row), 0].max)
|
|
745
|
+
else
|
|
746
|
+
lines << row
|
|
747
|
+
end
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
remaining = jobs.length - scroll_offset - data_rows
|
|
751
|
+
if remaining > 0
|
|
752
|
+
lines << @pastel.dim(" ↓ #{remaining} more")
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
# Status message
|
|
756
|
+
if @status_message && @status_time && (Time.now - @status_time) < 3
|
|
757
|
+
lines << @pastel.green(" #{@status_message}")
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
lines.join("\n")
|
|
761
|
+
end
|
|
762
|
+
|
|
604
763
|
def format_queue_row(queue, name_width)
|
|
605
764
|
name = truncate(queue[:name], name_width)
|
|
606
765
|
size = format_number(queue[:size])
|
|
@@ -1083,31 +1242,36 @@ module Sktop
|
|
|
1083
1242
|
end
|
|
1084
1243
|
|
|
1085
1244
|
def function_bar
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
end
|
|
1245
|
+
# Map keys to views for highlighting
|
|
1246
|
+
view_keys = {
|
|
1247
|
+
"m" => :main,
|
|
1248
|
+
"q" => :queues,
|
|
1249
|
+
"p" => :processes,
|
|
1250
|
+
"w" => :workers,
|
|
1251
|
+
"r" => :retries,
|
|
1252
|
+
"s" => :scheduled,
|
|
1253
|
+
"d" => :dead
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
items = [
|
|
1257
|
+
["m", "Main"],
|
|
1258
|
+
["q", "Queues"],
|
|
1259
|
+
["p", "Procs"],
|
|
1260
|
+
["w", "Workers"],
|
|
1261
|
+
["r", "Retries"],
|
|
1262
|
+
["s", "Sched"],
|
|
1263
|
+
["d", "Dead"],
|
|
1264
|
+
["^C", "Quit"]
|
|
1265
|
+
]
|
|
1108
1266
|
|
|
1109
1267
|
bar = items.map do |key, label|
|
|
1110
|
-
|
|
1268
|
+
view = view_keys[key]
|
|
1269
|
+
if view && view == @current_view
|
|
1270
|
+
# Highlight current view with inverted colors
|
|
1271
|
+
@pastel.black.on_white.bold(key) + @pastel.black.on_green.bold(label)
|
|
1272
|
+
else
|
|
1273
|
+
@pastel.black.on_cyan.bold(key) + @pastel.white.on_blue(label)
|
|
1274
|
+
end
|
|
1111
1275
|
end.join(" ")
|
|
1112
1276
|
|
|
1113
1277
|
width = terminal_width
|
data/lib/sktop/job_actions.rb
CHANGED
|
@@ -41,6 +41,15 @@ module Sktop
|
|
|
41
41
|
count
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def delete_queue_job(queue_name, jid)
|
|
45
|
+
queue = Sidekiq::Queue.new(queue_name)
|
|
46
|
+
job = queue.find { |j| j.jid == jid }
|
|
47
|
+
raise "Job not found in queue #{queue_name} (JID: #{jid})" unless job
|
|
48
|
+
|
|
49
|
+
job.delete
|
|
50
|
+
true
|
|
51
|
+
end
|
|
52
|
+
|
|
44
53
|
def quiet_process(identity)
|
|
45
54
|
process = find_process(identity)
|
|
46
55
|
raise "Process not found (identity: #{identity})" unless process
|
|
@@ -108,6 +108,19 @@ module Sktop
|
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
+
def queue_jobs(queue_name, limit: 100)
|
|
112
|
+
queue = Sidekiq::Queue.new(queue_name)
|
|
113
|
+
queue.first(limit).map do |job|
|
|
114
|
+
{
|
|
115
|
+
jid: job.jid,
|
|
116
|
+
class: job.klass,
|
|
117
|
+
args: job.args,
|
|
118
|
+
enqueued_at: job.enqueued_at,
|
|
119
|
+
created_at: job.created_at
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
111
124
|
def scheduled_jobs(limit: 10)
|
|
112
125
|
Sidekiq::ScheduledSet.new.first(limit).map do |job|
|
|
113
126
|
{
|
data/lib/sktop/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sktop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- James
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: sidekiq
|