cache_stache 0.2.0 → 0.2.1

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: d75f242cecde072c5db6fe680a47fcb3b98165a4d12cf46738d64b0c0956c7ef
4
- data.tar.gz: 86c3c5b676cb94ea1427cbed332f8fc97b2dac235ce22c031511a8ad1014d8b8
3
+ metadata.gz: 3b3e76904376faf81f690f9b8fd24d63c368295e9c133304b3c16bf0f6e48c6d
4
+ data.tar.gz: 3b23acace11232c359d8d9185946fcb595315ce89e4eacd5b9386de8290e9e71
5
5
  SHA512:
6
- metadata.gz: a4997e8c87c2cb1b974eeac87489b5ad6344adef9dd632d0c1f80429f4aae49edbe76ca4b70557d201a309575f8369a9f361207556c7bb6758630adf6240d174
7
- data.tar.gz: 623d1edd5b5a304e7839133d9bc4ae9fc9d8f1d67ec76d893df77c6ff506e6c5322b37c657eac5f42d9cbe617f689def250b4974f150f0a0d668348f00766709
6
+ metadata.gz: 0ed34798119cada11fbbf64f51a61a291e725288dba4fd4bc82353a1feca9adfbf3f654c1070c7664b3e4397f0d2f48cb6ca504cb4963d2a62d7af639fd68c16
7
+ data.tar.gz: 49d081eec0e40ae8d2dddb6159aef9b5524d369770d7826981b0e6a2da2c3cae90c50e6ae34ce7b263f76487ea6aa59a51d55a788c2884caa4f7a35108a685ef
data/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.1]
9
+
10
+ ### Fixed
11
+
12
+ - Fixed Redis calls when `bucket_seconds` or `retention_seconds` are configured with `ActiveSupport::Duration` values
13
+
14
+ ## [0.2.0]
15
+
16
+ ### Changed
17
+
18
+ - **Breaking:** Replaced `redis_url` config option with `redis`, which accepts a Proc, String URL, or Redis-compatible object
19
+
20
+ ## [0.1.1]
21
+
22
+ - Fixed Rails dependency to be >=, not ~>
23
+
24
+ ## [0.1.0]
25
+
26
+ ### Added
27
+
28
+ - Initial release
29
+ - Cache hit/miss rate tracking via Rails instrumentation
30
+ - Redis-backed statistics storage
31
+ - Dashboard UI for viewing cache metrics
32
+ - Keyspace breakdown view
33
+ - Configurable time windows (minute, hour, day)
34
+ - Rake tasks for cache statistics
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Nate Berkopec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -39,7 +39,7 @@ module CacheStache
39
39
  redis.eval(
40
40
  INCR_AND_EXPIRE_SCRIPT,
41
41
  keys: [key],
42
- argv: [@config.retention_seconds, increments.to_json]
42
+ argv: [retention_seconds, increments.to_json]
43
43
  )
44
44
  end
45
45
  end
@@ -79,16 +79,16 @@ module CacheStache
79
79
  def store_config_metadata
80
80
  key = "cache_stache:v1:#{@config.rails_env}:config"
81
81
  metadata = {
82
- bucket_seconds: @config.bucket_seconds,
83
- retention_seconds: @config.retention_seconds,
82
+ bucket_seconds: @config.bucket_seconds.to_i,
83
+ retention_seconds: retention_seconds,
84
84
  updated_at: Time.current.to_i
85
85
  }
86
86
 
87
87
  without_instrumentation do
88
88
  @pool.with do |redis|
89
89
  # Use SETEX for atomic set-with-expiry (single command)
90
- Rails.logger.debug { "CacheStache: Redis SETEX #{key} #{@config.retention_seconds}" }
91
- redis.setex(key, @config.retention_seconds, metadata.to_json)
90
+ Rails.logger.debug { "CacheStache: Redis SETEX #{key} #{retention_seconds}" }
91
+ redis.setex(key, retention_seconds, metadata.to_json)
92
92
  end
93
93
  end
94
94
  rescue => e
@@ -164,6 +164,10 @@ module CacheStache
164
164
  end
165
165
  end
166
166
 
167
+ def retention_seconds
168
+ @config.retention_seconds.to_i
169
+ end
170
+
167
171
  def bucket_key(timestamp)
168
172
  "cache_stache:v1:#{@config.rails_env}:#{timestamp}"
169
173
  end
@@ -7,13 +7,13 @@ module CacheStache
7
7
  class Configuration
8
8
  DEFAULT_REDIS_OPTIONS = {reconnect_attempts: 0}.freeze
9
9
 
10
- attr_accessor :bucket_seconds, :retention_seconds, :sample_rate, :enabled,
11
- :redis, :redis_pool_size, :use_rack_after_reply, :max_buckets
12
- attr_reader :keyspaces
10
+ attr_accessor :sample_rate, :enabled, :redis, :redis_pool_size,
11
+ :use_rack_after_reply, :max_buckets
12
+ attr_reader :bucket_seconds, :retention_seconds, :keyspaces
13
13
 
14
14
  def initialize
15
- @bucket_seconds = 5.minutes.to_i
16
- @retention_seconds = 7.days.to_i
15
+ self.bucket_seconds = 5.minutes
16
+ self.retention_seconds = 7.days
17
17
  @sample_rate = 1.0
18
18
  @enabled = rails_env != "test"
19
19
  @use_rack_after_reply = false
@@ -33,6 +33,14 @@ module CacheStache
33
33
  # :redis String -> Redis.new(url: redis)
34
34
  # :redis Object -> redis (assumed to be a Redis-compatible client)
35
35
  #
36
+ def bucket_seconds=(value)
37
+ @bucket_seconds = value.to_i
38
+ end
39
+
40
+ def retention_seconds=(value)
41
+ @retention_seconds = value.to_i
42
+ end
43
+
36
44
  def build_redis
37
45
  case redis
38
46
  when Proc
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CacheStache
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
@@ -75,6 +75,17 @@ RSpec.describe CacheStache::CacheClient do
75
75
  expect(ttl).to be <= config.retention_seconds
76
76
  end
77
77
 
78
+ it "increments stats when retention is configured with ActiveSupport::Duration" do
79
+ duration_config = build_test_config(retention_seconds: 7.days)
80
+ duration_client = described_class.new(duration_config)
81
+
82
+ duration_client.increment_stats(bucket_ts, increments)
83
+
84
+ buckets = duration_client.fetch_buckets(bucket_ts - 100, bucket_ts + 100)
85
+ expect(buckets.size).to eq(1)
86
+ expect(buckets.first[:stats]["overall:hits"]).to eq(1.0)
87
+ end
88
+
78
89
  it "handles errors gracefully" do
79
90
  # Create client, then make the pool raise errors
80
91
  test_client = described_class.new(config)
@@ -168,6 +179,17 @@ RSpec.describe CacheStache::CacheClient do
168
179
  expect(metadata["updated_at"]).to be_a(Integer)
169
180
  end
170
181
 
182
+ it "stores configuration metadata when durations use ActiveSupport::Duration" do
183
+ duration_config = build_test_config(bucket_seconds: 5.minutes, retention_seconds: 7.days)
184
+ duration_client = described_class.new(duration_config)
185
+
186
+ duration_client.store_config_metadata
187
+ metadata = duration_client.fetch_config_metadata
188
+
189
+ expect(metadata["bucket_seconds"]).to eq(5.minutes.to_i)
190
+ expect(metadata["retention_seconds"]).to eq(7.days.to_i)
191
+ end
192
+
171
193
  it "handles errors gracefully" do
172
194
  # Create client, then make the pool raise errors
173
195
  test_client = described_class.new(config)
@@ -24,6 +24,20 @@ RSpec.describe CacheStache::Configuration do
24
24
  it { expect(config.keyspaces).to eq([]) }
25
25
  end
26
26
 
27
+ describe "duration settings" do
28
+ it "coerces bucket_seconds to integer seconds" do
29
+ config.bucket_seconds = 5.minutes
30
+
31
+ expect(config.bucket_seconds).to eq(300)
32
+ end
33
+
34
+ it "coerces retention_seconds to integer seconds" do
35
+ config.retention_seconds = 7.days
36
+
37
+ expect(config.retention_seconds).to eq(604_800)
38
+ end
39
+ end
40
+
27
41
  describe "#build_redis" do
28
42
  it "calls the proc when redis is a Proc" do
29
43
  redis_instance = instance_double(Redis)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_stache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - CacheStache contributors
@@ -155,6 +155,8 @@ executables: []
155
155
  extensions: []
156
156
  extra_rdoc_files: []
157
157
  files:
158
+ - CHANGELOG.md
159
+ - LICENSE.txt
158
160
  - README.md
159
161
  - app/assets/stylesheets/cache_stache/application.css
160
162
  - app/assets/stylesheets/cache_stache/pico.css