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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdff64ca287bd83eaa37c48afbc375e4303b7d3cc8d368b80c1d996d9ad0e3c0
4
- data.tar.gz: 20d5d5fbc3afdd79d5a6d826a4a62419d1af60532e4b2515d4d9b2c0956e6174
3
+ metadata.gz: bdaf73fb205686d551ea90a70ffe82e93287c9fcb2e9209e25e626f200c84768
4
+ data.tar.gz: 778faad72b00b0f2b477df2ec53e107aba064d2cfe4e0a8b53a8d4623521d1ce
5
5
  SHA512:
6
- metadata.gz: 7de9f04b093e0ae1fadbd7f967fdf843aff8b7d530e766454848ac43afae8bce58228f4d8d3a05349d4d4983c7163b9063a31181de9eb0d30ac0fc3cac7da6b3
7
- data.tar.gz: '097252131a51b2dc34db4b8da6dc442ccaa01eb8c49334cfdd658bef9321330f7d8c75037e61abce08ffd6491673d92c75f7438419a964b022c6b53749159936'
6
+ metadata.gz: e860b5e07f84e20481463eb4bf36984e094b2f95c70d1be4c072318b7e089858b7355ca8e44476495354676ce403b4e4e5cf5e796376c1d155bb47bc60e9ea21
7
+ data.tar.gz: 902113917b4b1a376d850a6a9d2d54994bebdf52c4834680524a43d9407f71343899a07c2b206080d9de9e522d3538b3288e74f065152e3458ee4617fc8eb293
data/README.md CHANGED
@@ -1,12 +1,46 @@
1
1
  ![mudis_signet](design/mudis.png "Mudis")
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/mudis.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/mudis)
3
+ [![Gem Version](https://badge.fury.io/rb/mudis.svg?icon=si%3Arubygems&refresh=1)](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 rails app to provide a Mudis server.
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 ` | Enfirce hard memory limits on key size and reject if exceeded | `false`|
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 dependncy in your project and configure as needed.
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
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- MUDIS_VERSION = "0.3.0"
3
+ MUDIS_VERSION = "0.3.1"
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)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mudis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - kiebor81