sktop 0.1.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86d292cd32dcb0f28255792d7947bba1d3ce9c699b6c972e430bdd6a148ff19d
4
- data.tar.gz: dd106d1f794704bb5b90ce9159e16a9dc528c1b5b1e64360cbab32cc0004b765
3
+ metadata.gz: 5a3ed9a8721d477335f08d009c76cd65793b96ab0c0a045466ebdfa05a5e7f12
4
+ data.tar.gz: cba94dc737356f0b9295cc04c00155dd2cc7eb60372dec1774b60489ae4c476d
5
5
  SHA512:
6
- metadata.gz: 88075d4385f78dffa4ebf05fde4a399f55a32c8686d704140da2e2c25698ef79183ebd97b54899250364e092319395bf788ae5d7a67a1636afcb146d3ce0bd64
7
- data.tar.gz: '086ea5911610ddda133ebf0ad7b1babe19b892af802df24e38230d567c630a62974ab0aace15ff011f10bd4ab2612fd5dc2611ea598d89ce1eee635ba29c8f80'
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
- # Ignore fetch errors, will retry next interval
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
- # Wait for initial data (with timeout)
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
- return unless data
262
-
263
- @display.render_refresh_from_cache(data)
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: work["payload"]["class"],
71
- args: work["payload"]["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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sktop
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sktop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - James
@@ -123,14 +123,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
123
  requirements:
124
124
  - - ">="
125
125
  - !ruby/object:Gem::Version
126
- version: 2.7.0
126
+ version: 3.2.0
127
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  requirements: []
133
- rubygems_version: 3.5.16
133
+ rubygems_version: 3.5.22
134
134
  signing_key:
135
135
  specification_version: 4
136
136
  summary: CLI tool to monitor Sidekiq queues and processes