feat: add Redis result backend#7
Conversation
- Added RedisBackend struct to manage task metadata using Redis. - Implemented methods to store, retrieve, and delete task metadata. - Introduced configuration options for key prefix and result TTL. - Added an in-memory backend for testing purposes. - Included unit tests to verify functionality of the Redis backend.
There was a problem hiding this comment.
Pull Request Overview
Adds a Redis result backend feature for Celery-compatible task metadata storage, enabling task result persistence and retrieval with AsyncResult integration.
- Add
ResultBackendabstraction with Redis implementation for storing task states and results - Wire AsyncResult and task lifecycle hooks to persist states, propagate errors, and fetch results
- Document client usage with examples and sync codegen/tests for the new backend functionality
Reviewed Changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/backend/mod.rs | Core result backend trait and task metadata structures |
| src/backend/redis.rs | Redis implementation of the result backend |
| src/task/async_result.rs | Enhanced AsyncResult with backend integration for result fetching |
| src/app/trace.rs | Task lifecycle hooks to persist states via result backend |
| src/app/mod.rs | CeleryBuilder integration for result backend configuration |
| examples/redis_results.rs | Example demonstrating Redis result backend usage |
| tests/beat_codegen/mod.rs | Updated codegen tests with error handling |
| tests/app_codegen/mod.rs | Updated codegen tests with error handling |
| src/task/mod.rs | ResultValue trait for task return type serialization |
| README.md | Documentation updates for result backend feature |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| let key = self.key_for(&meta.task_id); | ||
|
|
||
| if let Some(ttl) = self.result_ttl { | ||
| conn.set_ex::<_, _, ()>(key, payload, ttl.as_secs()).await?; |
There was a problem hiding this comment.
Using ttl.as_secs() truncates sub-second precision. For TTL values less than 1 second, this will result in immediate expiration (0 seconds). Consider using set_ex with ttl.as_secs().max(1) or implement a more precise TTL handling approach.
| conn.set_ex::<_, _, ()>(key, payload, ttl.as_secs()).await?; | |
| conn.set_ex::<_, _, ()>(key, payload, ttl.as_secs().max(1)).await?; |
| let mut fallback = TaskMeta::success(self.task_id(), &()).unwrap(); | ||
| fallback.result = Some(Value::String(format!("{:?}", returned))); |
There was a problem hiding this comment.
The fallback serialization using format!(\"{:?}\", returned) may not produce valid JSON and could lose type information. Consider using a more structured approach like wrapping the debug string in a JSON object with metadata about the serialization failure.
Summary
ResultBackendabstraction with Redis implementation for Celery-compatible task metadata storageTesting
cargo testcargo test --test integrations(fails: requires local Redis + AMQP brokers)