sktop 0.1.4 → 0.1.5
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 +14 -11
- data/lib/sktop/display.rb +51 -4
- data/lib/sktop/stats_collector.rb +35 -2
- data/lib/sktop/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5a3ed9a8721d477335f08d009c76cd65793b96ab0c0a045466ebdfa05a5e7f12
|
|
4
|
+
data.tar.gz: cba94dc737356f0b9295cc04c00155dd2cc7eb60372dec1774b60489ae4c476d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e26bc9fe20fdb3d540c417802ca15db53b5263f52dcab6f696afb1b4cf6d52134e8dafe6d09abf8378e694fdb5c0307c61b7c84a0e523aee12f9db5b2cb00bd1
|
|
7
|
+
data.tar.gz: 93eac6acd09dda870a90311fbd606a54ee7ad072919bba959951ecec91e31eb75d01e4a851aec1f111f9e0f193328c0f02e3adad914a15afdd17c67c02ec6ea5
|
data/lib/sktop/cli.rb
CHANGED
|
@@ -164,6 +164,10 @@ module Sktop
|
|
|
164
164
|
# Set up signal handler for Ctrl+C (works even when blocked)
|
|
165
165
|
Signal.trap("INT") { @running = false }
|
|
166
166
|
|
|
167
|
+
# Render loading screen immediately
|
|
168
|
+
@display.connection_status = :connecting
|
|
169
|
+
@display.render_loading
|
|
170
|
+
|
|
167
171
|
# Start background thread for data fetching
|
|
168
172
|
fetch_thread = Thread.new do
|
|
169
173
|
while @running
|
|
@@ -179,6 +183,7 @@ module Sktop
|
|
|
179
183
|
next unless can_fetch
|
|
180
184
|
|
|
181
185
|
begin
|
|
186
|
+
@display.connection_status = :updating
|
|
182
187
|
collector.refresh!
|
|
183
188
|
# Cache a snapshot of the data
|
|
184
189
|
snapshot = {
|
|
@@ -194,8 +199,10 @@ module Sktop
|
|
|
194
199
|
@cached_data = snapshot
|
|
195
200
|
@data_version += 1
|
|
196
201
|
end
|
|
202
|
+
@display.connection_status = :connected
|
|
197
203
|
rescue => e
|
|
198
|
-
|
|
204
|
+
@display.connection_status = :error
|
|
205
|
+
# Will retry next interval
|
|
199
206
|
ensure
|
|
200
207
|
@fetch_mutex.synchronize { @fetch_in_progress = false }
|
|
201
208
|
end
|
|
@@ -211,13 +218,7 @@ module Sktop
|
|
|
211
218
|
begin
|
|
212
219
|
# Set up raw mode for keyboard input
|
|
213
220
|
STDIN.raw do |stdin|
|
|
214
|
-
#
|
|
215
|
-
10.times do
|
|
216
|
-
break if @data_mutex.synchronize { @cached_data }
|
|
217
|
-
sleep 0.1
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
# Initial render
|
|
221
|
+
# Initial render (will show loading or data if already fetched)
|
|
221
222
|
render_cached_data
|
|
222
223
|
|
|
223
224
|
while @running
|
|
@@ -258,9 +259,11 @@ module Sktop
|
|
|
258
259
|
|
|
259
260
|
def render_cached_data
|
|
260
261
|
data = @data_mutex.synchronize { @cached_data }
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
if data
|
|
263
|
+
@display.render_refresh_from_cache(data)
|
|
264
|
+
else
|
|
265
|
+
@display.render_loading
|
|
266
|
+
end
|
|
264
267
|
end
|
|
265
268
|
|
|
266
269
|
def handle_keypress(key, stdin)
|
data/lib/sktop/display.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Sktop
|
|
4
4
|
class Display
|
|
5
|
-
attr_accessor :current_view
|
|
5
|
+
attr_accessor :current_view, :connection_status, :last_update
|
|
6
6
|
|
|
7
7
|
def initialize
|
|
8
8
|
@pastel = Pastel.new
|
|
@@ -13,6 +13,8 @@ module Sktop
|
|
|
13
13
|
@selected_index = Hash.new(0) # Track selected row per view
|
|
14
14
|
@status_message = nil
|
|
15
15
|
@status_time = nil
|
|
16
|
+
@connection_status = :connecting # :connecting, :connected, :updating, :error
|
|
17
|
+
@last_update = nil
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def scroll_up
|
|
@@ -114,11 +116,24 @@ module Sktop
|
|
|
114
116
|
end
|
|
115
117
|
|
|
116
118
|
def render_refresh_from_cache(data)
|
|
119
|
+
@connection_status = :connected
|
|
120
|
+
@last_update = Time.now
|
|
117
121
|
cached = CachedData.new(data)
|
|
118
122
|
content = build_output(cached)
|
|
119
123
|
render_with_overwrite(content)
|
|
120
124
|
end
|
|
121
125
|
|
|
126
|
+
def render_loading
|
|
127
|
+
lines = []
|
|
128
|
+
lines << header_bar
|
|
129
|
+
lines << ""
|
|
130
|
+
lines << @pastel.cyan(" Connecting to Redis...")
|
|
131
|
+
lines << ""
|
|
132
|
+
lines << @pastel.dim(" Waiting for data...")
|
|
133
|
+
lines << :footer
|
|
134
|
+
render_with_overwrite(lines)
|
|
135
|
+
end
|
|
136
|
+
|
|
122
137
|
# Simple wrapper to make cached hash act like collector
|
|
123
138
|
class CachedData
|
|
124
139
|
def initialize(data)
|
|
@@ -370,15 +385,47 @@ module Sktop
|
|
|
370
385
|
timestamp = Time.now.strftime("%H:%M:%S")
|
|
371
386
|
title = "sktop"
|
|
372
387
|
|
|
388
|
+
# Connection status indicator
|
|
389
|
+
status_text = case @connection_status
|
|
390
|
+
when :connecting
|
|
391
|
+
@pastel.yellow.on_blue(" ● Connecting ")
|
|
392
|
+
when :updating
|
|
393
|
+
@pastel.cyan.on_blue(" ↻ Updating ")
|
|
394
|
+
when :error
|
|
395
|
+
@pastel.red.on_blue(" ✗ Error ")
|
|
396
|
+
else # :connected
|
|
397
|
+
if @last_update
|
|
398
|
+
age = Time.now - @last_update
|
|
399
|
+
if age < 5
|
|
400
|
+
@pastel.green.on_blue(" ● Connected ")
|
|
401
|
+
else
|
|
402
|
+
@pastel.green.on_blue(" ● #{format_update_age(age)} ago ")
|
|
403
|
+
end
|
|
404
|
+
else
|
|
405
|
+
@pastel.green.on_blue(" ● Connected ")
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
373
409
|
left = @pastel.white.on_blue.bold(" #{title} ")
|
|
374
410
|
right = @pastel.white.on_blue.bold(" #{timestamp} ")
|
|
375
411
|
|
|
376
412
|
left_len = visible_string_length(left)
|
|
413
|
+
status_len = visible_string_length(status_text)
|
|
377
414
|
right_len = visible_string_length(right)
|
|
378
|
-
middle_width = width - left_len - right_len
|
|
379
|
-
middle = @pastel.on_blue(" " * middle_width)
|
|
415
|
+
middle_width = width - left_len - status_len - right_len
|
|
416
|
+
middle = @pastel.on_blue(" " * [middle_width, 0].max)
|
|
380
417
|
|
|
381
|
-
left + middle + right
|
|
418
|
+
left + status_text + middle + right
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
def format_update_age(seconds)
|
|
422
|
+
if seconds < 60
|
|
423
|
+
"#{seconds.round}s"
|
|
424
|
+
elsif seconds < 3600
|
|
425
|
+
"#{(seconds / 60).round}m"
|
|
426
|
+
else
|
|
427
|
+
"#{(seconds / 3600).round}h"
|
|
428
|
+
end
|
|
382
429
|
end
|
|
383
430
|
|
|
384
431
|
def section_bar(title)
|
|
@@ -63,15 +63,48 @@ module Sktop
|
|
|
63
63
|
|
|
64
64
|
def workers
|
|
65
65
|
Sidekiq::Workers.new.map do |process_id, thread_id, work|
|
|
66
|
+
extract_worker_info(process_id, thread_id, work)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def extract_worker_info(process_id, thread_id, work)
|
|
71
|
+
# Sidekiq 7+ returns Work objects, older versions return hashes
|
|
72
|
+
if work.is_a?(Hash)
|
|
73
|
+
# Older Sidekiq - work is a hash with string keys
|
|
74
|
+
payload = work["payload"]
|
|
66
75
|
{
|
|
67
76
|
process_id: process_id,
|
|
68
77
|
thread_id: thread_id,
|
|
69
78
|
queue: work["queue"],
|
|
70
|
-
class:
|
|
71
|
-
args:
|
|
79
|
+
class: payload["class"],
|
|
80
|
+
args: payload["args"] || [],
|
|
72
81
|
run_at: Time.at(work["run_at"]),
|
|
73
82
|
elapsed: Time.now - Time.at(work["run_at"])
|
|
74
83
|
}
|
|
84
|
+
elsif work.respond_to?(:job)
|
|
85
|
+
# Sidekiq 7+ Work object with job accessor
|
|
86
|
+
job = work.job
|
|
87
|
+
{
|
|
88
|
+
process_id: process_id,
|
|
89
|
+
thread_id: thread_id,
|
|
90
|
+
queue: work.queue,
|
|
91
|
+
class: job["class"],
|
|
92
|
+
args: job["args"] || [],
|
|
93
|
+
run_at: Time.at(work.run_at),
|
|
94
|
+
elapsed: Time.now - Time.at(work.run_at)
|
|
95
|
+
}
|
|
96
|
+
else
|
|
97
|
+
# Fallback for other versions - try payload
|
|
98
|
+
payload = work.payload
|
|
99
|
+
{
|
|
100
|
+
process_id: process_id,
|
|
101
|
+
thread_id: thread_id,
|
|
102
|
+
queue: work.queue,
|
|
103
|
+
class: payload["class"],
|
|
104
|
+
args: payload["args"] || [],
|
|
105
|
+
run_at: Time.at(work.run_at),
|
|
106
|
+
elapsed: Time.now - Time.at(work.run_at)
|
|
107
|
+
}
|
|
75
108
|
end
|
|
76
109
|
end
|
|
77
110
|
|
data/lib/sktop/version.rb
CHANGED