legion-cache 1.2.0 → 1.3.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 +4 -4
- data/.github/workflows/ci.yml +19 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +39 -15
- data/CHANGELOG.md +32 -3
- data/CLAUDE.md +141 -0
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +105 -27
- data/legion-cache.gemspec +14 -14
- data/lib/legion/cache/local.rb +115 -0
- data/lib/legion/cache/memcached.rb +29 -9
- data/lib/legion/cache/pool.rb +4 -0
- data/lib/legion/cache/redis.rb +11 -3
- data/lib/legion/cache/settings.rb +53 -11
- data/lib/legion/cache/version.rb +1 -1
- data/lib/legion/cache.rb +81 -12
- metadata +23 -32
- data/.github/workflows/rubocop-analysis.yml +0 -28
- data/.github/workflows/sourcehawk-scan.yml +0 -20
- data/CODE_OF_CONDUCT.md +0 -75
- data/CONTRIBUTING.md +0 -55
- data/INDIVIDUAL_CONTRIBUTOR_LICENSE.md +0 -30
- data/NOTICE.txt +0 -9
- data/SECURITY.md +0 -9
- data/attribution.txt +0 -1
- data/sourcehawk.yml +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 657e7afe142d9420c0414c416fdf612ef75456262c91165d545112960bf44e71
|
|
4
|
+
data.tar.gz: 137d4eb307b337bcda85f91db10fddc42319793a99cde3038fbf9799db960d78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e167c6f650ad38373f8794f9cfc209857fd5053b9751375cf77f7ae9537eab23c40cd33947cc656c64dd77e7832f1312987739b4c95c1d2873b5cdf377aeff0d
|
|
7
|
+
data.tar.gz: 7e38075e7257b4b04fbdefb22de3da21d0055be631f8a6ca4f17d0c78f5669e153d0590aabd3742c05990f88c4e7c55d85409dfae90a5ec6741f36913af54f92
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
ci:
|
|
9
|
+
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
10
|
+
with:
|
|
11
|
+
needs-redis: true
|
|
12
|
+
needs-memcached: true
|
|
13
|
+
|
|
14
|
+
release:
|
|
15
|
+
needs: ci
|
|
16
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
17
|
+
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
18
|
+
secrets:
|
|
19
|
+
rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,26 +1,50 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 3.4
|
|
3
|
+
NewCops: enable
|
|
4
|
+
SuggestExtensions: false
|
|
5
|
+
|
|
1
6
|
Layout/LineLength:
|
|
2
|
-
Max:
|
|
3
|
-
|
|
4
|
-
|
|
7
|
+
Max: 160
|
|
8
|
+
|
|
9
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
|
10
|
+
EnforcedStyle: space
|
|
11
|
+
|
|
12
|
+
Layout/HashAlignment:
|
|
13
|
+
EnforcedHashRocketStyle: table
|
|
14
|
+
EnforcedColonStyle: table
|
|
15
|
+
|
|
5
16
|
Metrics/MethodLength:
|
|
6
|
-
Max:
|
|
17
|
+
Max: 50
|
|
18
|
+
|
|
7
19
|
Metrics/ClassLength:
|
|
8
20
|
Max: 1500
|
|
21
|
+
|
|
22
|
+
Metrics/ModuleLength:
|
|
23
|
+
Max: 1500
|
|
24
|
+
|
|
9
25
|
Metrics/BlockLength:
|
|
10
|
-
Max:
|
|
26
|
+
Max: 40
|
|
11
27
|
Exclude:
|
|
12
|
-
- 'spec
|
|
28
|
+
- 'spec/**/*'
|
|
29
|
+
|
|
13
30
|
Metrics/AbcSize:
|
|
14
|
-
Max:
|
|
31
|
+
Max: 60
|
|
32
|
+
|
|
33
|
+
Metrics/CyclomaticComplexity:
|
|
34
|
+
Max: 15
|
|
35
|
+
|
|
36
|
+
Metrics/PerceivedComplexity:
|
|
37
|
+
Max: 17
|
|
38
|
+
|
|
15
39
|
Style/Documentation:
|
|
16
40
|
Enabled: false
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
NewCops: enable
|
|
22
|
-
SuggestExtensions: false
|
|
41
|
+
|
|
42
|
+
Style/SymbolArray:
|
|
43
|
+
Enabled: true
|
|
44
|
+
|
|
23
45
|
Style/FrozenStringLiteralComment:
|
|
46
|
+
Enabled: true
|
|
47
|
+
EnforcedStyle: always
|
|
48
|
+
|
|
49
|
+
Naming/FileName:
|
|
24
50
|
Enabled: false
|
|
25
|
-
Gemspec/RequiredRubyVersion:
|
|
26
|
-
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
3
|
+
## [1.3.1] - 2026-03-20
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `Settings.normalize_driver` — maps `:memcached`, `:dalli`, `:redis` to internal gem names
|
|
7
|
+
- `Settings.resolve_servers` — merges `server:` (string) and `servers:` (array), injects default port per driver (memcached: 11211, redis: 6379), deduplicates
|
|
8
|
+
- `Settings::DEFAULT_PORTS` constant for driver default ports
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Redis driver now uses configured `server:`/`servers:` instead of hardcoded localhost
|
|
12
|
+
- Memcached driver accepts `server:` (singular) in addition to `servers:` (plural)
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- `Settings.default` and `Settings.local` use `resolve_servers` for driver-aware server defaults
|
|
16
|
+
- Driver selection in `cache.rb` and `local.rb` uses `normalize_driver` for consistent name handling
|
|
17
|
+
|
|
18
|
+
## [1.3.0] - 2026-03-16
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `Legion::Cache::Local` module for local Redis/Memcached caching
|
|
22
|
+
- `Settings.local` with independent defaults (namespace: `legion_local`, pool_size: 5, timeout: 3)
|
|
23
|
+
- Transparent fallback: shared cache failure at setup redirects all operations to Local
|
|
24
|
+
- `Legion::Cache.local` accessor, `Legion::Cache.using_local?` query
|
|
25
|
+
|
|
26
|
+
## [1.2.1] - 2026-03-16
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Set dalli `value_max_bytes` to 8MB by default — dalli enforces a 1MB client-side limit that prevented large cache values from being stored even when memcached server allows larger items
|
|
30
|
+
|
|
31
|
+
## [1.2.0]
|
|
32
|
+
|
|
33
|
+
Moving from BitBucket to GitHub. All git history is reset from this point on
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# legion-cache: Caching Layer for LegionIO
|
|
2
|
+
|
|
3
|
+
**Repository Level 3 Documentation**
|
|
4
|
+
- **Parent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
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
|
+
|
|
10
|
+
**GitHub**: https://github.com/LegionIO/legion-cache
|
|
11
|
+
**Version**: 1.3.0
|
|
12
|
+
**License**: Apache-2.0
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Legion::Cache (singleton module)
|
|
18
|
+
├── .setup(**opts) # Connect to cache backend
|
|
19
|
+
├── .get(key) # Retrieve cached value
|
|
20
|
+
├── .fetch(key, ttl) # Get with block/TTL support (Memcached only; alias for get on Redis)
|
|
21
|
+
├── .set(key, value, ttl) # Store value with optional TTL (positional on Memcached, keyword on Redis)
|
|
22
|
+
├── .delete(key) # Remove a key
|
|
23
|
+
├── .flush # Flush all keys (flush(delay) on Memcached, flushdb on Redis)
|
|
24
|
+
├── .connected? # Connection status
|
|
25
|
+
├── .size # Total pool connections
|
|
26
|
+
├── .available # Idle pool connections
|
|
27
|
+
├── .restart(**opts) # Close and reconnect pool with optional new opts
|
|
28
|
+
├── .shutdown # Close connections, mark disconnected
|
|
29
|
+
├── .local # Accessor for Legion::Cache::Local
|
|
30
|
+
├── .using_local? # Whether fallback to local is active
|
|
31
|
+
│
|
|
32
|
+
├── Memcached # Dalli-based Memcached driver (default)
|
|
33
|
+
│ └── Uses connection_pool for thread safety
|
|
34
|
+
│ └── value_max_bytes defaults to 8MB (overrides dalli's 1MB client-side limit)
|
|
35
|
+
├── Redis # Redis driver
|
|
36
|
+
│ └── Uses connection_pool for thread safety
|
|
37
|
+
│ └── Default pool_size is 20 (Memcached default is 10)
|
|
38
|
+
├── Local # Local cache tier (localhost Redis/Memcached, fallback target)
|
|
39
|
+
│ ├── .setup # Connect to local cache server (auto-detect driver)
|
|
40
|
+
│ ├── .shutdown # Close local connection
|
|
41
|
+
│ ├── .connected? # Whether local cache is active
|
|
42
|
+
│ ├── .get/set/delete/fetch/flush # Cache operations on local tier
|
|
43
|
+
│ ├── .restart(**opts) # Close and reconnect with new opts
|
|
44
|
+
│ └── .reset! # Clear all state (testing)
|
|
45
|
+
├── Pool # Connection pool management (connected?, size, available, close, restart)
|
|
46
|
+
├── Settings # Default cache config + driver auto-detection
|
|
47
|
+
└── Version
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Key Design Patterns
|
|
51
|
+
|
|
52
|
+
- **Driver Selection at Load Time**: `Legion::Settings[:cache][:driver]` determines which module gets `extend`ed into `Legion::Cache` (`'redis'` or `'dalli'`)
|
|
53
|
+
- **Connection Pooling**: Both drivers use `connection_pool` gem for thread-safe access
|
|
54
|
+
- **Unified Interface**: Same `get`/`set`/`delete`/`flush`/`connected?`/`shutdown` methods regardless of backend
|
|
55
|
+
- **TTL Signature Difference**: Memcached `set(key, value, ttl)` uses a positional TTL (default 180s); Redis `set(key, value, ttl: nil)` uses a keyword TTL
|
|
56
|
+
|
|
57
|
+
### Two-Tier Cache Architecture
|
|
58
|
+
|
|
59
|
+
- **Shared** (`Legion::Cache`) — remote Redis/Memcached cluster for cross-node caching
|
|
60
|
+
- **Local** (`Legion::Cache::Local`) — localhost Redis/Memcached for per-machine caching
|
|
61
|
+
- **Fallback**: If shared cluster is unreachable at setup, all operations transparently delegate to Local
|
|
62
|
+
- Both tiers use the same driver modules (`Memcached`/`Redis`) with independent connection pools
|
|
63
|
+
- Local uses `.dup` on the driver module to get isolated `@client`/`@connected` state
|
|
64
|
+
|
|
65
|
+
## Default Settings
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"driver": "dalli",
|
|
70
|
+
"servers": ["127.0.0.1:11211"],
|
|
71
|
+
"connected": false,
|
|
72
|
+
"enabled": true,
|
|
73
|
+
"namespace": "legion",
|
|
74
|
+
"compress": false,
|
|
75
|
+
"failover": true,
|
|
76
|
+
"threadsafe": true,
|
|
77
|
+
"cache_nils": false,
|
|
78
|
+
"pool_size": 10,
|
|
79
|
+
"timeout": 5,
|
|
80
|
+
"expires_in": 0,
|
|
81
|
+
"serializer": "Legion::JSON"
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The `driver` is auto-detected at load time: prefers `dalli`, falls back to `redis` if dalli is unavailable. Both gems are required dependencies so auto-detection is a fallback for unusual environments.
|
|
86
|
+
|
|
87
|
+
### Local Default Settings
|
|
88
|
+
|
|
89
|
+
`Legion::Cache::Settings.local` provides independent defaults for the local tier:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"driver": "dalli",
|
|
94
|
+
"servers": ["127.0.0.1:11211"],
|
|
95
|
+
"connected": false,
|
|
96
|
+
"enabled": true,
|
|
97
|
+
"namespace": "legion_local",
|
|
98
|
+
"compress": false,
|
|
99
|
+
"failover": false,
|
|
100
|
+
"threadsafe": true,
|
|
101
|
+
"cache_nils": false,
|
|
102
|
+
"pool_size": 5,
|
|
103
|
+
"timeout": 3,
|
|
104
|
+
"expires_in": 0,
|
|
105
|
+
"serializer": "Legion::JSON"
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Memcached value_max_bytes
|
|
110
|
+
|
|
111
|
+
Dalli enforces a 1MB client-side limit by default (`value_max_bytes: 1_048_576`). The Memcached driver overrides this to **8MB** (`8 * 1024 * 1024`) unless explicitly set. This prevents silent rejection of large cached values. The Memcached server must also be started with `-I 8m` to accept values up to 8MB server-side.
|
|
112
|
+
|
|
113
|
+
## Dependencies
|
|
114
|
+
|
|
115
|
+
| Gem | Purpose |
|
|
116
|
+
|-----|---------|
|
|
117
|
+
| `dalli` (>= 3.0) | Memcached client |
|
|
118
|
+
| `redis` (>= 5.0) | Redis client |
|
|
119
|
+
| `connection_pool` (>= 2.4) | Thread-safe connection pooling |
|
|
120
|
+
| `legion-logging` | Logging |
|
|
121
|
+
| `legion-settings` | Configuration |
|
|
122
|
+
|
|
123
|
+
## File Map
|
|
124
|
+
|
|
125
|
+
| Path | Purpose |
|
|
126
|
+
|------|---------|
|
|
127
|
+
| `lib/legion/cache.rb` | Module entry, driver selection, setup/shutdown, fallback wiring |
|
|
128
|
+
| `lib/legion/cache/memcached.rb` | Dalli/Memcached driver implementation |
|
|
129
|
+
| `lib/legion/cache/redis.rb` | Redis driver implementation |
|
|
130
|
+
| `lib/legion/cache/local.rb` | Local cache tier (localhost, fallback target) |
|
|
131
|
+
| `lib/legion/cache/pool.rb` | Connection pool management |
|
|
132
|
+
| `lib/legion/cache/settings.rb` | Default configuration + local defaults |
|
|
133
|
+
| `lib/legion/cache/version.rb` | VERSION constant |
|
|
134
|
+
|
|
135
|
+
## Role in LegionIO
|
|
136
|
+
|
|
137
|
+
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.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
**Maintained By**: Matthew Iverson (@Esity)
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright 2021
|
|
189
|
+
Copyright 2021 Esity
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
data/README.md
CHANGED
|
@@ -1,59 +1,137 @@
|
|
|
1
|
-
|
|
2
|
-
=====
|
|
1
|
+
# legion-cache
|
|
3
2
|
|
|
4
|
-
|
|
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.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
------------------------------------------------
|
|
5
|
+
**Version**: 1.3.1
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* JRuby 9.2+
|
|
12
|
-
* Ruby 2.4+
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Installation and Usage
|
|
16
|
-
------------------------
|
|
17
|
-
|
|
18
|
-
You can verify your installation using this piece of code:
|
|
7
|
+
## Installation
|
|
19
8
|
|
|
20
9
|
```bash
|
|
21
10
|
gem install legion-cache
|
|
22
11
|
```
|
|
23
12
|
|
|
13
|
+
Or add to your Gemfile:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
gem 'legion-cache'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
24
21
|
```ruby
|
|
25
22
|
require 'legion/cache'
|
|
26
23
|
|
|
27
24
|
Legion::Cache.setup
|
|
28
25
|
Legion::Cache.connected? # => true
|
|
26
|
+
|
|
27
|
+
# Memcached driver (default) — TTL is a positional argument, default 180s
|
|
28
|
+
Legion::Cache.set('foobar', 'testing', 10)
|
|
29
|
+
Legion::Cache.get('foobar') # => 'testing'
|
|
30
|
+
Legion::Cache.fetch('foobar') # => 'testing' (get with block support)
|
|
31
|
+
Legion::Cache.delete('foobar') # => true
|
|
32
|
+
Legion::Cache.flush # flush all keys
|
|
33
|
+
|
|
34
|
+
# Redis driver — TTL is a keyword argument
|
|
29
35
|
Legion::Cache.set('foobar', 'testing', ttl: 10)
|
|
30
|
-
Legion::Cache.get('foobar')
|
|
31
|
-
|
|
32
|
-
Legion::Cache.
|
|
36
|
+
Legion::Cache.get('foobar') # => 'testing'
|
|
37
|
+
Legion::Cache.delete('foobar') # => true
|
|
38
|
+
Legion::Cache.flush # flushdb
|
|
33
39
|
|
|
40
|
+
Legion::Cache.shutdown
|
|
34
41
|
```
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
## Two-Tier Cache
|
|
44
|
+
|
|
45
|
+
Legion::Cache supports a two-tier architecture: a shared remote cluster and a local per-machine cache. If the shared cluster is unreachable at setup, all operations transparently fall back to local.
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
# Shared cache connects to remote cluster; Local connects to localhost
|
|
49
|
+
Legion::Cache.setup # starts Local first, then tries shared
|
|
50
|
+
Legion::Cache.using_local? # => true if shared was unreachable
|
|
51
|
+
Legion::Cache.local # => Legion::Cache::Local
|
|
52
|
+
|
|
53
|
+
# Use Local directly if needed
|
|
54
|
+
Legion::Cache::Local.setup
|
|
55
|
+
Legion::Cache::Local.set('key', 'value', 60)
|
|
56
|
+
Legion::Cache::Local.get('key') # => 'value'
|
|
57
|
+
Legion::Cache::Local.shutdown
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Local uses a separate namespace (`legion_local`) and independent connection pool (pool_size: 5, timeout: 3) so it never collides with the shared tier.
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
38
63
|
|
|
39
64
|
```json
|
|
40
65
|
{
|
|
41
66
|
"driver": "dalli",
|
|
42
|
-
"servers": [
|
|
43
|
-
"127.0.0.1:11211"
|
|
44
|
-
],
|
|
67
|
+
"servers": ["127.0.0.1:11211"],
|
|
45
68
|
"connected": false,
|
|
46
69
|
"enabled": true,
|
|
47
70
|
"namespace": "legion",
|
|
48
71
|
"compress": false,
|
|
72
|
+
"failover": true,
|
|
73
|
+
"threadsafe": true,
|
|
49
74
|
"cache_nils": false,
|
|
50
75
|
"pool_size": 10,
|
|
51
|
-
"timeout":
|
|
76
|
+
"timeout": 5,
|
|
52
77
|
"expires_in": 0
|
|
53
78
|
}
|
|
54
79
|
```
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
|
|
81
|
+
The driver is auto-detected at load time: prefers `dalli` (Memcached) if available, falls back to `redis`. Override with `"driver": "redis"` and update `servers` to point at your Redis instance.
|
|
82
|
+
|
|
83
|
+
### Driver Names
|
|
84
|
+
|
|
85
|
+
Supported driver names: `memcached` (or `dalli`), `redis`. All names are normalized internally — `"memcached"` and `"dalli"` are equivalent.
|
|
86
|
+
|
|
87
|
+
### Server Resolution
|
|
88
|
+
|
|
89
|
+
Both `server` (singular string) and `servers` (array) are accepted and merged. Default ports are injected per driver when omitted: 11211 for memcached, 6379 for redis. Duplicates are removed.
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"cache": {
|
|
94
|
+
"driver": "memcached",
|
|
95
|
+
"server": "10.0.0.5",
|
|
96
|
+
"servers": ["10.0.0.6", "10.0.0.7:22122"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Memcached notes
|
|
102
|
+
|
|
103
|
+
- `value_max_bytes` defaults to **8MB**. Dalli enforces a 1MB client-side limit by default, which silently rejects large values. This default overrides that. Your Memcached server should also be started with `-I 8m` to match.
|
|
104
|
+
- Redis default pool size is 20; Memcached default pool size is 10.
|
|
105
|
+
|
|
106
|
+
### Local Cache Settings
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"driver": "dalli",
|
|
111
|
+
"servers": ["127.0.0.1:11211"],
|
|
112
|
+
"namespace": "legion_local",
|
|
113
|
+
"pool_size": 5,
|
|
114
|
+
"timeout": 3
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Override via `Legion::Settings[:cache_local]`.
|
|
119
|
+
|
|
120
|
+
## Pool API
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
Legion::Cache.connected? # => true/false
|
|
124
|
+
Legion::Cache.size # total pool connections
|
|
125
|
+
Legion::Cache.available # idle pool connections
|
|
126
|
+
Legion::Cache.restart # close and reconnect pool
|
|
127
|
+
Legion::Cache.shutdown # close pool and mark disconnected
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Requirements
|
|
131
|
+
|
|
132
|
+
- Ruby >= 3.4
|
|
133
|
+
- Memcached or Redis server
|
|
134
|
+
|
|
135
|
+
## License
|
|
58
136
|
|
|
59
|
-
|
|
137
|
+
Apache-2.0
|
data/legion-cache.gemspec
CHANGED
|
@@ -6,29 +6,29 @@ Gem::Specification.new do |spec|
|
|
|
6
6
|
spec.name = 'legion-cache'
|
|
7
7
|
spec.version = Legion::Cache::VERSION
|
|
8
8
|
spec.authors = ['Esity']
|
|
9
|
-
spec.email =
|
|
9
|
+
spec.email = ['matthewdiverson@gmail.com']
|
|
10
10
|
|
|
11
11
|
spec.summary = 'Wraps both the redis and dalli gems to make a consistent interface for accessing cached objects'
|
|
12
12
|
spec.description = 'A Wrapper class for the LegionIO framework to interface with both Memcached and Redis for caching purposes'
|
|
13
|
-
spec.homepage = 'https://github.com/
|
|
13
|
+
spec.homepage = 'https://github.com/LegionIO/legion-cache'
|
|
14
14
|
spec.license = 'Apache-2.0'
|
|
15
15
|
spec.require_paths = ['lib']
|
|
16
|
-
spec.required_ruby_version = '>=
|
|
16
|
+
spec.required_ruby_version = '>= 3.4'
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
-
spec.
|
|
19
|
-
spec.extra_rdoc_files = %w[README.md LICENSE CHANGELOG.md]
|
|
18
|
+
spec.extra_rdoc_files = %w[README.md LICENSE CHANGELOG.md]
|
|
20
19
|
spec.metadata = {
|
|
21
|
-
'bug_tracker_uri'
|
|
22
|
-
'changelog_uri'
|
|
23
|
-
'documentation_uri'
|
|
24
|
-
'homepage_uri'
|
|
25
|
-
'source_code_uri'
|
|
26
|
-
'wiki_uri'
|
|
20
|
+
'bug_tracker_uri' => 'https://github.com/LegionIO/legion-cache/issues',
|
|
21
|
+
'changelog_uri' => 'https://github.com/LegionIO/legion-cache/blob/main/CHANGELOG.md',
|
|
22
|
+
'documentation_uri' => 'https://github.com/LegionIO/legion-cache',
|
|
23
|
+
'homepage_uri' => 'https://github.com/LegionIO/LegionIO',
|
|
24
|
+
'source_code_uri' => 'https://github.com/LegionIO/legion-cache',
|
|
25
|
+
'wiki_uri' => 'https://github.com/LegionIO/legion-cache/wiki',
|
|
26
|
+
'rubygems_mfa_required' => 'true'
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
spec.add_dependency 'connection_pool', '>= 2.
|
|
30
|
-
spec.add_dependency 'dalli', '>=
|
|
29
|
+
spec.add_dependency 'connection_pool', '>= 2.4'
|
|
30
|
+
spec.add_dependency 'dalli', '>= 3.0'
|
|
31
31
|
spec.add_dependency 'legion-logging'
|
|
32
32
|
spec.add_dependency 'legion-settings'
|
|
33
|
-
spec.add_dependency 'redis', '>=
|
|
33
|
+
spec.add_dependency 'redis', '>= 5.0'
|
|
34
34
|
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/cache/settings'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Cache
|
|
7
|
+
module Local
|
|
8
|
+
class << self
|
|
9
|
+
def setup(**)
|
|
10
|
+
return if @connected
|
|
11
|
+
|
|
12
|
+
settings = local_settings
|
|
13
|
+
return unless settings[:enabled]
|
|
14
|
+
|
|
15
|
+
driver_name = settings[:driver] || Legion::Cache::Settings.driver
|
|
16
|
+
@driver = build_driver(driver_name)
|
|
17
|
+
@driver.client(**settings, **)
|
|
18
|
+
@connected = true
|
|
19
|
+
Legion::Logging.info "Legion::Cache::Local connected (#{driver_name})" if defined?(Legion::Logging)
|
|
20
|
+
rescue StandardError => e
|
|
21
|
+
Legion::Logging.warn "Legion::Cache::Local setup failed: #{e.message}" if defined?(Legion::Logging)
|
|
22
|
+
@connected = false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def shutdown
|
|
26
|
+
return unless @connected
|
|
27
|
+
|
|
28
|
+
Legion::Logging.info 'Shutting down Legion::Cache::Local' if defined?(Legion::Logging)
|
|
29
|
+
@driver&.close
|
|
30
|
+
@driver = nil
|
|
31
|
+
@connected = false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def connected?
|
|
35
|
+
@connected == true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def get(key)
|
|
39
|
+
@driver.get(key)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def set(key, value, ttl = 180)
|
|
43
|
+
@driver.set(key, value, ttl)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def fetch(key, ttl = nil)
|
|
47
|
+
@driver.fetch(key, ttl)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def delete(key)
|
|
51
|
+
@driver.delete(key)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def flush(delay = 0)
|
|
55
|
+
@driver.flush(delay)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def client
|
|
59
|
+
@driver&.client
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def close
|
|
63
|
+
@driver&.close
|
|
64
|
+
@connected = false
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def restart(**opts)
|
|
68
|
+
settings = local_settings
|
|
69
|
+
@driver&.restart(**settings.merge(opts))
|
|
70
|
+
@connected = true
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def size
|
|
74
|
+
@driver.size
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def available
|
|
78
|
+
@driver.available
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def pool_size
|
|
82
|
+
@driver.pool_size
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def timeout
|
|
86
|
+
@driver.timeout
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def reset!
|
|
90
|
+
@driver = nil
|
|
91
|
+
@connected = false
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def build_driver(driver_name)
|
|
97
|
+
case Legion::Cache::Settings.normalize_driver(driver_name)
|
|
98
|
+
when 'redis'
|
|
99
|
+
require 'legion/cache/redis'
|
|
100
|
+
Legion::Cache::Redis.dup
|
|
101
|
+
else
|
|
102
|
+
require 'legion/cache/memcached'
|
|
103
|
+
Legion::Cache::Memcached.dup
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def local_settings
|
|
108
|
+
return Legion::Cache::Settings.local unless defined?(Legion::Settings)
|
|
109
|
+
|
|
110
|
+
Legion::Settings[:cache_local] || Legion::Cache::Settings.local
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|