solid_cache_dashboard 0.0.1 → 0.2.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 +18 -1
- data/app/assets/javascripts/solid_cache_dashboard/application.js +2 -1
- data/app/assets/stylesheets/solid_cache_dashboard/application.css +778 -12
- data/app/assets/stylesheets/solid_cache_dashboard/tailwind.css +8 -8
- data/app/controllers/solid_cache_dashboard/cache_entries_controller.rb +16 -3
- data/app/controllers/solid_cache_dashboard/cache_events_controller.rb +9 -3
- data/app/views/layouts/solid_cache_dashboard/application.html.erb +1 -1
- data/app/views/solid_cache_dashboard/application/_footer.html.erb +2 -2
- data/app/views/solid_cache_dashboard/application/_navbar.html.erb +28 -7
- data/app/views/solid_cache_dashboard/application/_pagination.html.erb +61 -0
- data/app/views/solid_cache_dashboard/cache_entries/index.html.erb +75 -27
- data/app/views/solid_cache_dashboard/cache_entries/show.html.erb +172 -39
- data/app/views/solid_cache_dashboard/cache_events/index.html.erb +34 -28
- data/app/views/solid_cache_dashboard/dashboard/index.html.erb +41 -41
- data/app/views/solid_cache_dashboard/stats/index.html.erb +55 -55
- data/lib/solid_cache_dashboard/cache_entry.rb +33 -0
- data/lib/solid_cache_dashboard/decorators/cache_entry_decorator.rb +92 -11
- data/lib/solid_cache_dashboard/engine.rb +13 -0
- data/lib/solid_cache_dashboard/instrumentation.rb +18 -9
- data/lib/solid_cache_dashboard/version.rb +1 -1
- metadata +17 -2
@@ -10,14 +10,13 @@ module SolidCacheDashboard
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def key
|
13
|
-
|
14
|
-
readable_key.match?(/^[-+\/=A-Za-z0-9]+$/) ? readable_key : key_hash
|
13
|
+
@entry.key
|
15
14
|
rescue
|
16
15
|
key_hash
|
17
16
|
end
|
18
17
|
|
19
18
|
def value
|
20
|
-
@value ||=
|
19
|
+
@value ||= @entry.value.to_s
|
21
20
|
rescue
|
22
21
|
"Binary data"
|
23
22
|
end
|
@@ -35,25 +34,107 @@ module SolidCacheDashboard
|
|
35
34
|
end
|
36
35
|
|
37
36
|
def created_at_ago
|
38
|
-
time_ago_in_words(created_at)
|
37
|
+
time_ago_in_words(created_at, Time.now)
|
39
38
|
end
|
40
39
|
|
41
|
-
|
40
|
+
def status
|
41
|
+
expires_at.present? && expires_at <= Time.now ? SolidCacheDashboard::CacheEntry::EXPIRED : SolidCacheDashboard::CacheEntry::ACTIVE
|
42
|
+
end
|
43
|
+
|
44
|
+
def status_badge
|
45
|
+
status_text = status.to_s.capitalize
|
46
|
+
color = SolidCacheDashboard::CacheEntry.status_color(status)
|
47
|
+
|
48
|
+
"<span class='inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-#{color}-100 dark:bg-#{color}-800 text-#{color}-800 dark:text-#{color}-100'>#{status_text}</span>".html_safe
|
49
|
+
end
|
50
|
+
|
51
|
+
def expires_at
|
52
|
+
return unless @entry.respond_to?(:expires_at)
|
53
|
+
@entry.expires_at
|
54
|
+
end
|
55
|
+
|
56
|
+
def expires_in
|
57
|
+
return unless expires_at
|
58
|
+
|
59
|
+
if expires_at <= Time.now
|
60
|
+
"Expired #{time_ago_in_words(expires_at, Time.now)}"
|
61
|
+
else
|
62
|
+
time_ago_in_words(Time.now, expires_at)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def encrypted?
|
67
|
+
return false unless defined?(SolidCache.configuration)
|
68
|
+
SolidCache.configuration.encrypt?
|
69
|
+
end
|
70
|
+
|
71
|
+
def encryption_status
|
72
|
+
encrypted? ? "Encrypted" : "Not encrypted"
|
73
|
+
end
|
74
|
+
|
75
|
+
def estimated_row_overhead
|
76
|
+
if encrypted?
|
77
|
+
SolidCache::Entry::ESTIMATED_ROW_OVERHEAD + SolidCache::Entry::ESTIMATED_ENCRYPTION_OVERHEAD
|
78
|
+
else
|
79
|
+
SolidCache::Entry::ESTIMATED_ROW_OVERHEAD
|
80
|
+
end
|
81
|
+
rescue NameError
|
82
|
+
140 # fallback to default ESTIMATED_ROW_OVERHEAD
|
83
|
+
end
|
84
|
+
|
85
|
+
def key_size
|
86
|
+
@entry.key.to_s.bytesize
|
87
|
+
end
|
88
|
+
|
89
|
+
def value_size
|
90
|
+
@entry.value.to_s.bytesize
|
91
|
+
end
|
92
|
+
|
93
|
+
def overhead_size
|
94
|
+
byte_size - key_size - value_size
|
95
|
+
end
|
96
|
+
|
97
|
+
def overhead_percentage
|
98
|
+
return 0 if byte_size == 0
|
99
|
+
(overhead_size.to_f / byte_size * 100).round(1)
|
100
|
+
end
|
42
101
|
|
43
|
-
def
|
44
|
-
|
102
|
+
def total_lifetime
|
103
|
+
return nil unless expires_at && created_at
|
104
|
+
|
105
|
+
distance_in_seconds = (expires_at - created_at).round
|
45
106
|
|
46
107
|
case distance_in_seconds
|
47
108
|
when 0..59
|
48
|
-
"#{distance_in_seconds} seconds
|
109
|
+
"#{distance_in_seconds} seconds"
|
110
|
+
when 60..3599
|
111
|
+
"#{(distance_in_seconds / 60).round} minutes"
|
112
|
+
when 3600..86399
|
113
|
+
"#{(distance_in_seconds / 3600).round} hours"
|
114
|
+
else
|
115
|
+
"#{(distance_in_seconds / 86400).round} days"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def time_ago_in_words(from_time, to_time = Time.now)
|
120
|
+
distance_in_seconds = (to_time - from_time).abs.round
|
121
|
+
suffix = to_time > from_time ? "ago" : "from now"
|
122
|
+
|
123
|
+
time_words = case distance_in_seconds
|
124
|
+
when 0..59
|
125
|
+
"#{distance_in_seconds} seconds"
|
49
126
|
when 60..3599
|
50
|
-
"#{(distance_in_seconds / 60).round} minutes
|
127
|
+
"#{(distance_in_seconds / 60).round} minutes"
|
51
128
|
when 3600..86399
|
52
|
-
"#{(distance_in_seconds / 3600).round} hours
|
129
|
+
"#{(distance_in_seconds / 3600).round} hours"
|
53
130
|
else
|
54
|
-
"#{(distance_in_seconds / 86400).round} days
|
131
|
+
"#{(distance_in_seconds / 86400).round} days"
|
55
132
|
end
|
133
|
+
|
134
|
+
"#{time_words} #{suffix}"
|
56
135
|
end
|
136
|
+
|
137
|
+
private
|
57
138
|
end
|
58
139
|
end
|
59
140
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'pagy'
|
2
|
+
|
1
3
|
module SolidCacheDashboard
|
2
4
|
class Engine < ::Rails::Engine
|
3
5
|
isolate_namespace SolidCacheDashboard
|
@@ -15,5 +17,16 @@ module SolidCacheDashboard
|
|
15
17
|
SolidCacheDashboard::Instrumentation.install
|
16
18
|
end
|
17
19
|
end
|
20
|
+
|
21
|
+
initializer "solid_cache_dashboard.pagy" do
|
22
|
+
# Include Pagy modules in application controller and views
|
23
|
+
ActiveSupport.on_load(:action_controller) do
|
24
|
+
include Pagy::Backend
|
25
|
+
end
|
26
|
+
|
27
|
+
ActiveSupport.on_load(:action_view) do
|
28
|
+
include Pagy::Frontend
|
29
|
+
end
|
30
|
+
end
|
18
31
|
end
|
19
32
|
end
|
@@ -7,14 +7,14 @@ module SolidCacheDashboard
|
|
7
7
|
def self.install
|
8
8
|
ActiveSupport::Notifications.subscribe("cache_read.active_support") do |*args|
|
9
9
|
event = ActiveSupport::Notifications::Event.new(*args)
|
10
|
-
|
11
|
-
|
10
|
+
key = event.payload[:key].to_s
|
11
|
+
key_hash = calculate_key_hash(key)
|
12
12
|
hit = event.payload[:hit]
|
13
13
|
|
14
14
|
SolidCacheDashboard::CacheEvent.create!(
|
15
15
|
event_type: hit ? SolidCacheDashboard::CacheEvent::HIT : SolidCacheDashboard::CacheEvent::MISS,
|
16
16
|
key_hash: key_hash,
|
17
|
-
key_string:
|
17
|
+
key_string: key.truncate(100),
|
18
18
|
duration: event.duration / 1000.0, # Convert from ms to seconds
|
19
19
|
created_at: Time.current
|
20
20
|
)
|
@@ -22,8 +22,8 @@ module SolidCacheDashboard
|
|
22
22
|
|
23
23
|
ActiveSupport::Notifications.subscribe("cache_write.active_support") do |*args|
|
24
24
|
event = ActiveSupport::Notifications::Event.new(*args)
|
25
|
-
|
26
|
-
|
25
|
+
key = event.payload[:key].to_s
|
26
|
+
key_hash = calculate_key_hash(key)
|
27
27
|
|
28
28
|
entry_size = nil
|
29
29
|
if event.payload[:entry]
|
@@ -33,7 +33,7 @@ module SolidCacheDashboard
|
|
33
33
|
SolidCacheDashboard::CacheEvent.create!(
|
34
34
|
event_type: SolidCacheDashboard::CacheEvent::WRITE,
|
35
35
|
key_hash: key_hash,
|
36
|
-
key_string:
|
36
|
+
key_string: key.truncate(100),
|
37
37
|
byte_size: entry_size,
|
38
38
|
duration: event.duration / 1000.0, # Convert from ms to seconds
|
39
39
|
created_at: Time.current
|
@@ -42,17 +42,26 @@ module SolidCacheDashboard
|
|
42
42
|
|
43
43
|
ActiveSupport::Notifications.subscribe("cache_delete.active_support") do |*args|
|
44
44
|
event = ActiveSupport::Notifications::Event.new(*args)
|
45
|
-
|
46
|
-
|
45
|
+
key = event.payload[:key].to_s
|
46
|
+
key_hash = calculate_key_hash(key)
|
47
47
|
|
48
48
|
SolidCacheDashboard::CacheEvent.create!(
|
49
49
|
event_type: SolidCacheDashboard::CacheEvent::DELETE,
|
50
50
|
key_hash: key_hash,
|
51
|
-
key_string:
|
51
|
+
key_string: key.truncate(100),
|
52
52
|
duration: event.duration / 1000.0, # Convert from ms to seconds
|
53
53
|
created_at: Time.current
|
54
54
|
)
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
# Calculate the key hash in the same way SolidCache::Entry does
|
59
|
+
def self.calculate_key_hash(key)
|
60
|
+
require 'digest'
|
61
|
+
|
62
|
+
# Need to unpack this as a signed integer - Same method used in SolidCache::Entry
|
63
|
+
# See: Digest::SHA256.digest(key.to_s).unpack("q>").first
|
64
|
+
Digest::SHA256.digest(key.to_s).unpack("q>").first
|
65
|
+
end
|
57
66
|
end
|
58
67
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solid_cache_dashboard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrea Fomera
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-02-
|
10
|
+
date: 2025-02-27 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: solid_cache
|
@@ -51,6 +51,20 @@ dependencies:
|
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '5.0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: pagy
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '6.0'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '6.0'
|
54
68
|
description: Dashboard for Solid Cache
|
55
69
|
email:
|
56
70
|
- afomera@hey.com
|
@@ -75,6 +89,7 @@ files:
|
|
75
89
|
- app/views/solid_cache_dashboard/application/_flash_messages.html.erb
|
76
90
|
- app/views/solid_cache_dashboard/application/_footer.html.erb
|
77
91
|
- app/views/solid_cache_dashboard/application/_navbar.html.erb
|
92
|
+
- app/views/solid_cache_dashboard/application/_pagination.html.erb
|
78
93
|
- app/views/solid_cache_dashboard/cache_entries/index.html.erb
|
79
94
|
- app/views/solid_cache_dashboard/cache_entries/show.html.erb
|
80
95
|
- app/views/solid_cache_dashboard/cache_events/index.html.erb
|