mudis 0.3.0 → 0.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/README.md +43 -7
- data/lib/mudis/version.rb +1 -1
- data/lib/mudis.rb +6 -0
- data/spec/mudis_spec.rb +5 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdaf73fb205686d551ea90a70ffe82e93287c9fcb2e9209e25e626f200c84768
|
4
|
+
data.tar.gz: 778faad72b00b0f2b477df2ec53e107aba064d2cfe4e0a8b53a8d4623521d1ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e860b5e07f84e20481463eb4bf36984e094b2f95c70d1be4c072318b7e089858b7355ca8e44476495354676ce403b4e4e5cf5e796376c1d155bb47bc60e9ea21
|
7
|
+
data.tar.gz: 902113917b4b1a376d850a6a9d2d54994bebdf52c4834680524a43d9407f71343899a07c2b206080d9de9e522d3538b3288e74f065152e3458ee4617fc8eb293
|
data/README.md
CHANGED
@@ -1,12 +1,46 @@
|
|
1
1
|

|
2
2
|
|
3
|
-
[](https://badge.fury.io/rb/mudis)
|
3
|
+
[](https://badge.fury.io/rb/mudis)
|
4
4
|
|
5
5
|
**Mudis** is a fast, thread-safe, in-memory, sharded LRU (Least Recently Used) cache for Ruby applications. Inspired by Redis, it provides value serialization, optional compression, per-key expiry, and metric tracking in a lightweight, dependency-free package that lives inside your Ruby process.
|
6
6
|
|
7
|
-
It’s ideal for scenarios where performance and process-local caching are critical, and where a full Redis setup is overkill or otherwise not possible.
|
7
|
+
It’s ideal for scenarios where performance and process-local caching are critical, and where a full Redis setup is overkill or otherwise not possible/desirable.
|
8
8
|
|
9
|
-
Alternatively, Mudis can be upscaled with higher sharding and resources in a dedicated
|
9
|
+
Alternatively, Mudis can be upscaled with higher sharding and resources in a dedicated Rails app to provide a Mudis server.
|
10
|
+
|
11
|
+
### Why another Caching Gem?
|
12
|
+
|
13
|
+
There are plenty out there, in various states of maintenance and in many shapes and sizes. So why on earth do we need another? I needed a drop-in replacement for Kredis, and the reason I was interested in using Kredis was for the simplified API and keyed management it gave me in extension to Redis. But what I didn't really need was Redis. I needed an observable, fast, simple, easy to use, flexible and highly configurable, thread-safe and high performant caching system which didn't require too many dependencies or standing up additional services. So, Mudis was born. In its most rudimentary state it was extremely useful in my project, which was an API gateway connecting into mutliple micro-services and a wide selection of APIs. The majority of the data was cold and produced by repeat expensive queries across several domains. Mudis allowed for me to minimize the footprint of the gateway, and improve end user experience, and increase performance. So, yeah, there's a lot of these gems out there, but none which really met all my needs. I decided to provide Mudis for anyone else. If you use it, I'd be interested to know how and whether you got any benefit.
|
14
|
+
|
15
|
+
#### Similar Gems
|
16
|
+
|
17
|
+
- [FastCache](https://github.com/swoop-inc/fast_cache)
|
18
|
+
- [EasyCache](https://github.com/malvads/easycache)
|
19
|
+
- [MiniCache](https://github.com/derrickreimer/mini_cache)
|
20
|
+
- [Zache](https://github.com/yegor256/zache)
|
21
|
+
|
22
|
+
#### Feature / Function Comparison
|
23
|
+
|
24
|
+
| **Feature** | **Mudis v0.3.0** | **MemoryStore** (`Rails.cache`) | **FastCache** | **Zache** | **EasyCache** | **MiniCache** |
|
25
|
+
| -------------------------------------- | ---------------- | ------------------------------- | -------------- | ------------- | ------------- | -------------- |
|
26
|
+
| **LRU eviction strategy** | ✅ Per-bucket | ✅ Global | ✅ Global | ❌ | ❌ | ✅ Simplistic |
|
27
|
+
| **TTL expiry support** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
28
|
+
| **Background expiry cleanup thread** | ✅ | ❌ (only on access) | ❌ | ✅ | ❌ | ❌ |
|
29
|
+
| **Thread safety** | ✅ Bucketed | ⚠️ Global lock | ✅ Fine-grained | ✅ | ⚠️ | ⚠️ |
|
30
|
+
| **Sharding (buckets)** | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
31
|
+
| **Custom serializers** | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
32
|
+
| **Compression (Zlib)** | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
33
|
+
| **Hard memory cap** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
34
|
+
| **Max value size enforcement** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
35
|
+
| **Metrics (hits, misses, evictions)** | ✅ | ⚠️ Partial | ❌ | ❌ | ❌ | ❌ |
|
36
|
+
| **Fetch/update pattern** | ✅ Full | ✅ Standard | ⚠️ Partial | ✅ Basic | ✅ Basic | ✅ Basic |
|
37
|
+
| **Namespacing** | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
38
|
+
| **Replace (if exists)** | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
39
|
+
| **Clear/delete method** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
40
|
+
| **Key inspection with metadata** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
41
|
+
| **Concurrency model** | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
42
|
+
| **Maintenance level** | ✅ | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ |
|
43
|
+
| **Suitable for APIs or microservices** | ✅ | ⚠️ Limited | ✅ | ⚠️ Small apps | ⚠️ Small apps | ❌ |
|
10
44
|
|
11
45
|
---
|
12
46
|
|
@@ -61,6 +95,7 @@ Mudis.compress = true # Compress values using Zlib
|
|
61
95
|
Mudis.max_value_bytes = 2_000_000 # Reject values > 2MB
|
62
96
|
Mudis.start_expiry_thread(interval: 60) # Cleanup every 60s
|
63
97
|
Mudis.hard_memory_limit = true # enforce hard memory limits
|
98
|
+
Mudis.max_bytes = 1_073_741_824 # set maximum cache size
|
64
99
|
|
65
100
|
at_exit do
|
66
101
|
Mudis.stop_expiry_thread
|
@@ -219,7 +254,8 @@ end
|
|
219
254
|
| `Mudis.max_value_bytes` | Max allowed size in bytes for a value | `nil` (no limit) |
|
220
255
|
| `Mudis.buckets` | Number of cache shards (via ENV var) | `32` |
|
221
256
|
| `start_expiry_thread` | Background TTL cleanup loop (every N sec) | Disabled by default|
|
222
|
-
| `hard_memory_limit
|
257
|
+
| `hard_memory_limit` | Enforce hard memory limits on key size and reject if exceeded | `false`|
|
258
|
+
| `max_bytes` | Maximum allowed cache size | `1GB`|
|
223
259
|
|
224
260
|
To customize the number of buckets, set the `MUDIS_BUCKETS` environment variable.
|
225
261
|
|
@@ -244,7 +280,7 @@ Based on 100000 iterations
|
|
244
280
|
| marshal + zlib | 100000 | 1.8057 | 55381 |
|
245
281
|
| json + zlib | 100000 | 2.7949 | 35780 |
|
246
282
|
|
247
|
-
> If opting for OJ, you will need to install the
|
283
|
+
> If opting for OJ, you will need to install the dependency in your project and configure as needed.
|
248
284
|
|
249
285
|
---
|
250
286
|
|
@@ -275,8 +311,6 @@ at_exit { Mudis.stop_expiry_thread }
|
|
275
311
|
|
276
312
|
MIT License © kiebor81
|
277
313
|
|
278
|
-
---
|
279
|
-
|
280
314
|
## Contributing
|
281
315
|
|
282
316
|
PRs are welcome! To get started:
|
@@ -293,3 +327,5 @@ bundle install
|
|
293
327
|
## Contact
|
294
328
|
|
295
329
|
For issues, suggestions, or feedback, please open a GitHub issue
|
330
|
+
|
331
|
+
---
|
data/lib/mudis/version.rb
CHANGED
data/lib/mudis.rb
CHANGED
@@ -18,11 +18,17 @@ class Mudis # rubocop:disable Metrics/ClassLength
|
|
18
18
|
|
19
19
|
class << self
|
20
20
|
attr_accessor :serializer, :compress, :max_value_bytes, :hard_memory_limit
|
21
|
+
attr_reader :max_bytes
|
21
22
|
|
22
23
|
# Returns a snapshot of metrics (thread-safe)
|
23
24
|
def metrics
|
24
25
|
@metrics_mutex.synchronize { @metrics.dup }
|
25
26
|
end
|
27
|
+
|
28
|
+
def max_bytes=(value)
|
29
|
+
@max_bytes = value
|
30
|
+
@threshold_bytes = (@max_bytes * 0.9).to_i
|
31
|
+
end
|
26
32
|
end
|
27
33
|
|
28
34
|
# Node structure for the LRU doubly-linked list
|
data/spec/mudis_spec.rb
CHANGED
@@ -216,6 +216,11 @@ RSpec.describe Mudis do # rubocop:disable Metrics/BlockLength
|
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
|
+
it "respects max_bytes when updated externally" do
|
220
|
+
Mudis.max_bytes = 100
|
221
|
+
expect(Mudis.send(:max_bytes)).to eq(100)
|
222
|
+
end
|
223
|
+
|
219
224
|
describe ".current_memory_bytes" do
|
220
225
|
it "returns a non-zero byte count after writes" do
|
221
226
|
Mudis.write("size_test", "a" * 100)
|