Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: LuckyCache Redis Store CI

on:
push:
branches: [main]
pull_request:
branches: "*"

jobs:
check_format:
strategy:
fail-fast: false
runs-on: ubuntu-latest
continue-on-error: false
steps:
- name: Download source
uses: actions/checkout@v3
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
- name: Install shards
run: shards install
- name: Format
run: crystal tool format --check
- name: Lint
run: ./bin/ameba
specs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
crystal_version: [latest]
include:
- os: ubuntu-latest
crystal_version: 1.4.0
runs-on: ${{ matrix.os }}
continue-on-error: false
services:
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v3
- uses: crystal-lang/install-crystal@v1
with:
crystal: ${{ matrix.crystal_version }}
- name: Install dependencies
run: shards install --skip-postinstall --skip-executables
- name: Run tests
run: crystal spec
23 changes: 23 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Deploy docs

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
- uses: crystal-lang/install-crystal@v1
- name: "Install shards"
run: shards install
- name: "Generate docs"
run: crystal docs
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
81 changes: 75 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# LuckyCacheRedisStore
# LuckyCache Redis Store

An adapter for [LuckyCache](https://github.com/luckyframework/lucky_cache/) to store
data in Redis.
A Redis storage backend for [LuckyCache](https://github.com/luckyframework/lucky_cache/), providing distributed caching capabilities for Lucky Framework applications.

## Installation

Expand All @@ -20,14 +19,84 @@ data in Redis.
## Usage

```crystal
require "lucky_cache"
require "lucky_cache_redis_store"
require "redis"

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
```

TODO: Write usage instructions here
### 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
```

### 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::Cachable` 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("[email protected]") } # This will raise an error

# Cache a JSON representation
user_data = {"id" => 123, "email" => "[email protected]"}
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

TODO: Write development instructions here
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
- Expiration functionality
- Key deletion and cache flushing
- Custom prefix support
- Error handling for non-serializable types

## Contributing

Expand All @@ -39,4 +108,4 @@ TODO: Write development instructions here

## Contributors

- [your-name-here](https://github.com/your-github-user) - creator and maintainer
- [Jeremy Woertink](https://github.com/jwoertink) - creator and maintainer
10 changes: 8 additions & 2 deletions shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ crystal: '>= 1.14.1'

license: MIT

dependencies:
redis:
github: jgaskins/redis
lucky_cache:
github: luckyframework/lucky_cache

development_dependencies:
ameba:
github: crystal-ameba/ameba
version: ~> 1.5.0
lucky_cache:
github: luckyframework/lucky_cache
timecop:
github: crystal-community/timecop.cr
Loading