https://github.com/luckyframework/lucky_cache_redis_store
An adapter for LuckyCache to store cache in Redis
https://github.com/luckyframework/lucky_cache_redis_store
Last synced: 3 months ago
JSON representation
An adapter for LuckyCache to store cache in Redis
- Host: GitHub
- URL: https://github.com/luckyframework/lucky_cache_redis_store
- Owner: luckyframework
- License: mit
- Created: 2025-07-03T15:20:47.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2026-03-24T23:27:31.000Z (3 months ago)
- Last Synced: 2026-03-26T04:59:45.489Z (3 months ago)
- Language: Crystal
- Size: 33.2 KB
- Stars: 0
- Watchers: 0
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# LuckyCache Redis Store
A Redis storage backend for [LuckyCache](https://github.com/luckyframework/lucky_cache/), providing distributed caching capabilities for Lucky Framework applications.
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
lucky_cache_redis_store:
github: luckyframework/lucky_cache_redis_store
```
2. Run `shards install`
## Usage
```crystal
require "lucky_cache_redis_store"
LuckyCache.configure do |settings|
settings.storage = LuckyCache::RedisStore.new(
Redis::Client.new(host: "localhost", port: 6379),
prefix: "myapp:cache:"
)
settings.default_duration = 5.minutes
end
```
### Basic Usage
```crystal
cache = LuckyCache.settings.storage
# Write to cache
cache.write("my_key", expires_in: 1.hour) { "my value" }
# Read from cache
if item = cache.read("my_key")
puts item.value # => "my value"
end
# Fetch (read-through cache)
value = cache.fetch("computed_key", as: String, expires_in: 10.minutes) do
# This block is only executed if the key doesn't exist
expensive_computation
end
# Delete from cache
cache.delete("my_key")
# Clear all cached items with the configured prefix
cache.flush
```
## Expiration Semantics
- `expires_in` is stored with millisecond precision.
- TTL values must be at least `1.millisecond`.
- `0.seconds`, negative durations, and positive durations below `1.millisecond` raise `ArgumentError`.
- `read` restores cache items with their original TTL metadata and the correct absolute expiration time.
## Prefix Operations
- `flush` removes only keys that match the store's configured prefix.
- `size` counts only keys that match the configured prefix.
- Both operations iterate Redis with `SCAN`, not `KEYS`, so they remain safer on larger keyspaces.
### Supported Types
The Redis store supports the following types:
- Basic types: `String`, `Int32`, `Int64`, `Float64`, `Bool`, `Time`, `UUID`, `JSON::Any`
- Arrays of basic types: `Array(String)`, `Array(Int32)`, `Array(Int64)`, `Array(Float64)`, `Array(Bool)`
**Note:** Custom objects that include `LuckyCache::Cacheable` are not supported by RedisStore due to serialization limitations. Use MemoryStore for caching custom objects.
### Workaround for Custom Objects
You can cache JSON representations of your objects:
```crystal
# Instead of caching the object directly
# cache.write("user:123") { User.new("test@example.com") } # This will raise an error
# Cache a JSON representation
user_data = {
"id" => JSON::Any.new(123_i64),
"email" => JSON::Any.new("test@example.com"),
}
cache.write("user:123") { JSON::Any.new(user_data) }
# Retrieve and reconstruct
cached_data = cache.read("user:123").not_nil!.value.as(JSON::Any)
user = User.new(cached_data["email"].as_s)
```
## Development
To run the tests:
1. Make sure Redis is running locally on the default port (`6379`)
2. Run `crystal spec`
The test suite includes tests for:
- Basic type caching
- Array type caching
- Millisecond TTL handling and TTL validation
- Expiration correctness after Redis deserialization
- Key deletion, prefix-scoped flushing, and prefix-scoped sizing
- Standalone shard loading
- Custom prefix support
- Error handling for non-serializable types
## Contributing
1. Fork it ()
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
## Contributors
- [Jeremy Woertink](https://github.com/jwoertink) - creator and maintainer