legion-cache 1.3.17 → 1.3.18

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: 2d0de0aa53a2886b16a2d2e10bb18e37128a0e0d50d118d689c8f87aa15fcb72
4
- data.tar.gz: 49387e7f795a779e595b700c2afe8eda19b7bc0e07273306ae57ca9ec71b2782
3
+ metadata.gz: aded92a74b60ff3cae8cab7d33d38f147bf17ac308dfd78695b2e6e2ed70298e
4
+ data.tar.gz: 244c88d6428745bd91d949dc7738cf65392e644d2143b3c092ab9b84fc610cd2
5
5
  SHA512:
6
- metadata.gz: af05e3b8f771a81307f9c3fb81c6dcb6a9fad154bd127660d71a9e645c44636fb1317ef70db618fa5e139fb617d012747bb477017226b829cc5d26ff3db6cd5a
7
- data.tar.gz: 0e31e8c387e44ff1c8e4089cabd04536df39e373cbc38bc90dc1beba85b080d92d77887ee1f4faccf4ef96bb0a02bc51d43bdebda53231e627d26f57e014775f
6
+ metadata.gz: d6b790d262f8d9735c7d3a31a5222b449408deb00126f5184b8404fafbfa95a30a2eb3826a1cff5c0a44420fe0510399ff47c002ec816b65f596079977d00e4b
7
+ data.tar.gz: 774eb4fd9532934894e4d38ab52cba094e5fbab03c33eeb12f9aae0a244efebfddf3eea454a97445598143de680e2eac01ddd6b4f256b4ce116408e398c07e50
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.3.18] - 2026-03-29
6
+
7
+ ### Added
8
+ - Layered TTL resolution in Helper (per-call → LEX override → Settings → FALLBACK_TTL)
9
+ - `cache_default_ttl` / `local_cache_default_ttl` — LEX-overridable default TTL methods
10
+ - `cache_exist?` / `local_cache_exist?` — key existence checks
11
+ - `cache_connected?` / `local_cache_connected?` — connection status helpers
12
+ - `cache_pool_size` / `cache_pool_available` — pool info (shared tier)
13
+ - `local_cache_pool_size` / `local_cache_pool_available` — pool info (local tier)
14
+ - `phi:` keyword argument on `cache_set` / `local_cache_set` for PHI TTL enforcement
15
+ - `default_ttl` key in Settings.default and Settings.local (defaults to 60)
16
+
5
17
  ## [1.3.17] - 2026-03-25
6
18
 
7
19
  ### Added
data/CLAUDE.md CHANGED
@@ -8,7 +8,7 @@
8
8
  Caching wrapper for the LegionIO framework. Provides a consistent interface for Memcached (via `dalli`) and Redis (via `redis` gem) with connection pooling. Driver selection is config-driven.
9
9
 
10
10
  **GitHub**: https://github.com/LegionIO/legion-cache
11
- **Version**: 1.3.12
11
+ **Version**: 1.3.17
12
12
  **License**: Apache-2.0
13
13
 
14
14
  ## Architecture
@@ -39,6 +39,7 @@ Legion::Cache (singleton module)
39
39
  ├── Memory # Lite mode adapter: pure in-memory cache, TTL expiry, Mutex thread-safety
40
40
  │ └── Activated by LEGION_MODE=lite env var; no Redis/Memcached required
41
41
  ├── Helper # Injectable cache mixin for LEX extensions (namespaced cache_*/local_cache_*)
42
+ ├── RedisHash # Redis-specific sorted set + hash operations (hset/hgetall/hdel/zadd/zrangebyscore/zrem/expire); Redis-only, module_function pattern
42
43
  ├── Local # Local cache tier (localhost Redis/Memcached, fallback target)
43
44
  │ ├── .setup # Connect to local cache server (auto-detect driver)
44
45
  │ ├── .shutdown # Close local connection
@@ -134,10 +135,25 @@ Dalli enforces a 1MB client-side limit by default (`value_max_bytes: 1_048_576`)
134
135
  | `lib/legion/cache/memory.rb` | Lite mode Memory adapter: in-memory store with TTL + Mutex thread-safety |
135
136
  | `lib/legion/cache/helper.rb` | Injectable cache mixin for LEX extensions |
136
137
  | `lib/legion/cache/local.rb` | Local cache tier (localhost, fallback target) |
138
+ | `lib/legion/cache/redis_hash.rb` | Redis sorted set + hash operations (hset/hgetall/hdel/zadd/zrangebyscore/zrem/expire) |
137
139
  | `lib/legion/cache/pool.rb` | Connection pool management |
138
140
  | `lib/legion/cache/settings.rb` | Default configuration + local defaults |
139
141
  | `lib/legion/cache/version.rb` | VERSION constant |
140
142
 
143
+ ## PHI TTL Cap
144
+
145
+ When `phi: true` is passed to `set`, the TTL is capped at `cache.compliance.phi_max_ttl` (default 3600s). This enforces the HIPAA PHI TTL policy in legion-logging. The `enforce_phi_ttl(ttl, phi: false)` method applies the cap; without `phi: true` the TTL is passed through unchanged.
146
+
147
+ ```json
148
+ {
149
+ "cache": {
150
+ "compliance": {
151
+ "phi_max_ttl": 3600
152
+ }
153
+ }
154
+ }
155
+ ```
156
+
141
157
  ## Role in LegionIO
142
158
 
143
159
  Optional caching layer initialized during `Legion::Service` startup. Used by `legion-data` for model caching (Sequel caching plugin) and by extensions for general-purpose caching.
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Caching wrapper for the [LegionIO](https://github.com/LegionIO/LegionIO) framework. Provides a consistent interface for Memcached (via `dalli`) and Redis (via `redis` gem) with connection pooling. Driver selection is config-driven.
4
4
 
5
- **Version**: 1.3.12
5
+ **Version**: 1.3.17
6
6
 
7
7
  ## Installation
8
8
 
@@ -3,12 +3,38 @@
3
3
  module Legion
4
4
  module Cache
5
5
  module Helper
6
+ FALLBACK_TTL = 60
7
+
8
+ # --- TTL Resolution ---
9
+ # Override in your LEX to set a custom default TTL for the extension.
10
+ # Resolution chain: per-call ttl: kwarg -> LEX override -> Settings -> FALLBACK_TTL
11
+ def cache_default_ttl
12
+ return FALLBACK_TTL unless defined?(Legion::Settings)
13
+
14
+ Legion::Settings.dig(:cache, :default_ttl) || FALLBACK_TTL
15
+ rescue StandardError
16
+ FALLBACK_TTL
17
+ end
18
+
19
+ def local_cache_default_ttl
20
+ return cache_default_ttl unless defined?(Legion::Settings)
21
+
22
+ Legion::Settings.dig(:cache_local, :default_ttl) || cache_default_ttl
23
+ rescue StandardError
24
+ cache_default_ttl
25
+ end
26
+
27
+ # --- Namespace ---
28
+
6
29
  def cache_namespace
7
30
  @cache_namespace ||= derive_cache_namespace
8
31
  end
9
32
 
10
- def cache_set(key, value, ttl: 60)
11
- Legion::Cache.set(cache_namespace + key, value, ttl)
33
+ # --- Core Operations (shared tier) ---
34
+
35
+ def cache_set(key, value, ttl: nil, phi: false)
36
+ effective_ttl = ttl || cache_default_ttl
37
+ Legion::Cache.set(cache_namespace + key, value, effective_ttl, phi: phi)
12
38
  end
13
39
 
14
40
  def cache_get(key)
@@ -19,12 +45,21 @@ module Legion
19
45
  Legion::Cache.delete(cache_namespace + key)
20
46
  end
21
47
 
22
- def cache_fetch(key, ttl: 60, &)
23
- Legion::Cache.fetch(cache_namespace + key, ttl, &)
48
+ def cache_fetch(key, ttl: nil, &)
49
+ effective_ttl = ttl || cache_default_ttl
50
+ Legion::Cache.fetch(cache_namespace + key, effective_ttl, &)
51
+ end
52
+
53
+ def cache_exist?(key)
54
+ !Legion::Cache.get(cache_namespace + key).nil?
24
55
  end
25
56
 
26
- def local_cache_set(key, value, ttl: 60)
27
- Legion::Cache::Local.set(cache_namespace + key, value, ttl)
57
+ # --- Core Operations (local tier) ---
58
+
59
+ def local_cache_set(key, value, ttl: nil, phi: false)
60
+ effective_ttl = ttl || local_cache_default_ttl
61
+ effective_ttl = Legion::Cache.enforce_phi_ttl(effective_ttl, phi: phi)
62
+ Legion::Cache::Local.set(cache_namespace + key, value, effective_ttl)
28
63
  end
29
64
 
30
65
  def local_cache_get(key)
@@ -35,8 +70,57 @@ module Legion
35
70
  Legion::Cache::Local.delete(cache_namespace + key)
36
71
  end
37
72
 
38
- def local_cache_fetch(key, ttl: 60, &)
39
- Legion::Cache::Local.fetch(cache_namespace + key, ttl, &)
73
+ def local_cache_fetch(key, ttl: nil, &)
74
+ effective_ttl = ttl || local_cache_default_ttl
75
+ Legion::Cache::Local.fetch(cache_namespace + key, effective_ttl, &)
76
+ end
77
+
78
+ def local_cache_exist?(key)
79
+ !Legion::Cache::Local.get(cache_namespace + key).nil?
80
+ end
81
+
82
+ # --- Status ---
83
+
84
+ def cache_connected?
85
+ Legion::Cache.connected?
86
+ end
87
+
88
+ def local_cache_connected?
89
+ Legion::Cache::Local.connected?
90
+ end
91
+
92
+ # --- Pool Info ---
93
+
94
+ def cache_pool_size
95
+ return 0 unless cache_connected?
96
+
97
+ Legion::Cache.pool_size
98
+ rescue StandardError
99
+ 0
100
+ end
101
+
102
+ def cache_pool_available
103
+ return 0 unless cache_connected?
104
+
105
+ Legion::Cache.available
106
+ rescue StandardError
107
+ 0
108
+ end
109
+
110
+ def local_cache_pool_size
111
+ return 0 unless local_cache_connected?
112
+
113
+ Legion::Cache::Local.pool_size
114
+ rescue StandardError
115
+ 0
116
+ end
117
+
118
+ def local_cache_pool_available
119
+ return 0 unless local_cache_connected?
120
+
121
+ Legion::Cache::Local.available
122
+ rescue StandardError
123
+ 0
40
124
  end
41
125
 
42
126
  private
@@ -25,6 +25,7 @@ module Legion
25
25
  cache_nils: false,
26
26
  pool_size: 10,
27
27
  timeout: 5,
28
+ default_ttl: 60,
28
29
  serializer: Legion::JSON,
29
30
  cluster: nil,
30
31
  replica: false,
@@ -50,6 +51,7 @@ module Legion
50
51
  cache_nils: false,
51
52
  pool_size: 5,
52
53
  timeout: 3,
54
+ default_ttl: 60,
53
55
  serializer: Legion::JSON,
54
56
  username: nil,
55
57
  password: nil,
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module Cache
5
- VERSION = '1.3.17'
5
+ VERSION = '1.3.18'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.17
4
+ version: 1.3.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity