From 9f18b6ca9b48a81121f9fc41ba241207bb637f67 Mon Sep 17 00:00:00 2001 From: Orne Brocaar Date: Tue, 28 Nov 2023 11:58:27 +0000 Subject: [PATCH] Merge deadpool-redis-cluster into deadpool-redis. --- README.md | 1 - redis-cluster/CHANGELOG.md | 5 - redis-cluster/Cargo.toml | 42 ------ redis-cluster/README.md | 122 ------------------ redis/CHANGELOG.md | 5 + redis/Cargo.toml | 6 +- redis/README.md | 89 ++++++++++++- .../src => redis/src/cluster}/config.rs | 8 +- .../src/lib.rs => redis/src/cluster/mod.rs | 46 +++---- redis/src/lib.rs | 2 + .../redis.rs => redis/tests/redis_cluster.rs | 10 +- test-build.sh | 9 +- 12 files changed, 134 insertions(+), 211 deletions(-) delete mode 100644 redis-cluster/CHANGELOG.md delete mode 100644 redis-cluster/Cargo.toml delete mode 100644 redis-cluster/README.md rename {redis-cluster/src => redis/src/cluster}/config.rs (97%) rename redis-cluster/src/lib.rs => redis/src/cluster/mod.rs (72%) rename redis-cluster/tests/redis.rs => redis/tests/redis_cluster.rs (92%) diff --git a/README.md b/README.md index db481c51..6185d22c 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,6 @@ Backend | Crate | Latest Version | [tokio-postgres](https://crates.io/crates/tokio-postgres) | [deadpool-postgres](https://crates.io/crates/deadpool-postgres) | [![Latest Version](https://img.shields.io/crates/v/deadpool-postgres.svg)](https://crates.io/crates/deadpool-postgres) | [lapin](https://crates.io/crates/lapin) (AMQP) | [deadpool-lapin](https://crates.io/crates/deadpool-lapin) | [![Latest Version](https://img.shields.io/crates/v/deadpool-lapin.svg)](https://crates.io/crates/deadpool-lapin) | [redis](https://crates.io/crates/redis) | [deadpool-redis](https://crates.io/crates/deadpool-redis) | [![Latest Version](https://img.shields.io/crates/v/deadpool-redis.svg)](https://crates.io/crates/deadpool-redis) | -[redis_cluster_async](https://crates.io/crates/redis_cluster_async) | [deadpool-redis-cluster](https://crates.io/crates/deadpool-redis-cluster) | [![Latest Version](https://img.shields.io/crates/v/deadpool-redis.svg)](https://crates.io/crates/deadpool-redis-cluster) | [async-memcached](https://crates.io/crates/async-memcached) | [deadpool-memcached](https://crates.io/crates/deadpool-memcached) | [![Latest Version](https://img.shields.io/crates/v/deadpool-memcached.svg)](https://crates.io/crates/deadpool-memcached) | [rusqlite](https://crates.io/crates/rusqlite) | [deadpool-sqlite](https://crates.io/crates/deadpool-sqlite) | [![Latest Version](https://img.shields.io/crates/v/deadpool-sqlite.svg)](https://crates.io/crates/deadpool-sqlite) | [diesel](https://crates.io/crates/diesel) | [deadpool-diesel](https://crates.io/crates/deadpool-diesel) | [![Latest Version](https://img.shields.io/crates/v/deadpool-diesel.svg)](https://crates.io/crates/deadpool-diesel) | diff --git a/redis-cluster/CHANGELOG.md b/redis-cluster/CHANGELOG.md deleted file mode 100644 index 502a9739..00000000 --- a/redis-cluster/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Change Log - -## v0.1.0 - -* First release diff --git a/redis-cluster/Cargo.toml b/redis-cluster/Cargo.toml deleted file mode 100644 index 60e37690..00000000 --- a/redis-cluster/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "deadpool-redis-cluster" -version = "0.1.0" -edition = "2021" -resolver = "2" -rust-version = "1.63" -authors = [ - "Michael P. Jung ", - "Subeom Choi ", -] -description = "Dead simple async pool for redis-cluster" -keywords = ["async", "redis-cluster", "pool"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/bikeshedder/deadpool" -readme = "README.md" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[features] -default = ["rt_tokio_1"] -rt_tokio_1 = ["deadpool/rt_tokio_1", "redis/tokio-comp"] -rt_async-std_1 = ["deadpool/rt_async-std_1", "redis/async-std-comp"] -serde = ["deadpool/serde", "serde_1"] - -[dependencies] -deadpool = { path = "../", version = "0.10.0", default-features = false, features = [ - "managed", -] } -redis = { version = "0.23.0", default-features = false, features = ["aio"] } -redis_cluster_async = "0.8.0" -serde_1 = { package = "serde", version = "1.0.145", features = [ - "derive", -], optional = true } - -[dev-dependencies] -config = { version = "0.13.2", features = ["json"] } -dotenv = "0.15.0" -futures = "0.3.24" -redis = { version = "0.23.0", default-features = false, features = ["aio"] } -tokio = { version = "1.21.2", features = ["full"] } diff --git a/redis-cluster/README.md b/redis-cluster/README.md deleted file mode 100644 index 422c31e8..00000000 --- a/redis-cluster/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Deadpool for Redis Cluster [![Latest Version](https://img.shields.io/crates/v/deadpool-redis-cluster.svg)](https://crates.io/crates/deadpool-redis-cluster) ![Unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg "Unsafe forbidden") [![Rust 1.63+](https://img.shields.io/badge/rustc-1.63+-lightgray.svg "Rust 1.63+")](https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html) - -Deadpool is a dead simple async pool for connections and objects -of any type. - -This crate implements a [`deadpool`](https://crates.io/crates/deadpool) -manager for [`redis-cluster`](https://crates.io/crates/redis_cluster_async). - -## Features - -| Feature | Description | Extra dependencies | Default | -| ---------------- | --------------------------------------------------------------------- | ------------------------------------------------- | ------- | -| `rt_tokio_1` | Enable support for [tokio](https://crates.io/crates/tokio) crate | `deadpool/rt_tokio_1`, `redis/tokio-comp` | yes | -| `rt_async-std_1` | Enable support for [async-std](https://crates.io/crates/config) crate | `deadpool/rt_async-std_1`, `redis/async-std-comp` | no | -| `serde` | Enable support for [serde](https://crates.io/crates/serde) crate | `deadpool/serde`, `serde/derive` | no | - -## Example - -```rust -use std::env; -use deadpool_redis_cluster::{redis::{cmd, FromRedisValue}, Config, Runtime}; - -#[tokio::main] -async fn main() { - let redis_urls = env::var("REDIS_CLUSTER__URLS") - .unwrap() - .split(',') - .map(String::from) - .collect::>(); - let mut cfg = Config::from_urls(redis_urls); - let pool = cfg.create_pool(Some(Runtime::Tokio1)).unwrap(); - { - let mut conn = pool.get().await.unwrap(); - cmd("SET") - .arg(&["deadpool/test_key", "42"]) - .query_async::<_, ()>(&mut conn) - .await.unwrap(); - } - { - let mut conn = pool.get().await.unwrap(); - let value: String = cmd("GET") - .arg(&["deadpool/test_key"]) - .query_async(&mut conn) - .await.unwrap(); - assert_eq!(value, "42".to_string()); - } -} -``` - -## Example with `config` and `dotenv` crate - -```rust -use deadpool_redis_cluster::{redis::{cmd, FromRedisValue}, Runtime}; -use dotenv::dotenv; -# use serde_1 as serde; - -#[derive(Debug, serde::Deserialize)] -# #[serde(crate = "serde_1")] -struct Config { - #[serde(default)] - redis_cluster: deadpool_redis_cluster::Config -} - -impl Config { - pub fn from_env() -> Result { - config::Config::builder() - .add_source( - config::Environment::default() - .separator("__") - .try_parsing(true) - .list_separator(","), - ) - .build()? - .try_deserialize() - } -} - -#[tokio::main] -async fn main() { - dotenv().ok(); - let cfg = Config::from_env().unwrap(); - let pool = cfg.redis_cluster.create_pool(Some(Runtime::Tokio1)).unwrap(); - { - let mut conn = pool.get().await.unwrap(); - cmd("SET") - .arg(&["deadpool/test_key", "42"]) - .query_async::<_, ()>(&mut conn) - .await.unwrap(); - } - { - let mut conn = pool.get().await.unwrap(); - let value: String = cmd("GET") - .arg(&["deadpool/test_key"]) - .query_async(&mut conn) - .await.unwrap(); - assert_eq!(value, "42".to_string()); - } -} -``` - -## FAQ - -- **How can I enable features of the `redis` crate?** - - Make sure that you depend on the same version of `redis` as - `deadpool-redis-cluster` does and enable the needed features in your own - `Crate.toml` file: - - ```toml - [dependencies] - deadpool-redis-cluster = { version = "0.9", features = ["serde"] } - redis = { version = "0.21", default-features = false, features = ["tls"] } - ``` - -## License - -Licensed under either of - -- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) -- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) - -at your option. diff --git a/redis/CHANGELOG.md b/redis/CHANGELOG.md index a203dde2..6ac92327 100644 --- a/redis/CHANGELOG.md +++ b/redis/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## v0.14.0 + +* Merge `deadpool-redis-cluster` into `deadpool-redis`. +* Remove `redis_cluster_async` dependency in favor of `redis::cluster` / `redis::cluster_async`. + ## v0.13.0 * Update `deadpool` dependency to version `0.10` diff --git a/redis/Cargo.toml b/redis/Cargo.toml index f51313b8..e9eccc23 100644 --- a/redis/Cargo.toml +++ b/redis/Cargo.toml @@ -4,7 +4,10 @@ version = "0.13.0" edition = "2018" resolver = "2" rust-version = "1.63" -authors = ["Michael P. Jung "] +authors = [ + "Michael P. Jung ", + "Subeom Choi ", +] description = "Dead simple async pool for redis" keywords = ["async", "redis", "pool"] license = "MIT OR Apache-2.0" @@ -20,6 +23,7 @@ default = ["rt_tokio_1"] rt_tokio_1 = ["deadpool/rt_tokio_1", "redis/tokio-comp"] rt_async-std_1 = ["deadpool/rt_async-std_1", "redis/async-std-comp"] serde = ["deadpool/serde", "serde_1"] +cluster = ["redis/cluster-async"] [dependencies] deadpool = { path = "../", version = "0.10.0", default-features = false, features = [ diff --git a/redis/README.md b/redis/README.md index 5402f6df..345d74dd 100644 --- a/redis/README.md +++ b/redis/README.md @@ -13,6 +13,7 @@ manager for [`redis`](https://crates.io/crates/redis). | `rt_tokio_1` | Enable support for [tokio](https://crates.io/crates/tokio) crate | `deadpool/rt_tokio_1`, `redis/tokio-comp` | yes | | `rt_async-std_1` | Enable support for [async-std](https://crates.io/crates/config) crate | `deadpool/rt_async-std_1`, `redis/async-std-comp` | no | | `serde` | Enable support for [serde](https://crates.io/crates/serde) crate | `deadpool/serde`, `serde/derive` | no | +| `cluster` | Enable support for Redis Cluster | `redis/cluster-async` | no | ## Example @@ -43,7 +44,7 @@ async fn main() { } ``` -## Example with `config` and `dotenv` crate +### Example with `config` and `dotenv` crate ```rust use deadpool_redis::{redis::{cmd, FromRedisValue}, Runtime}; @@ -89,6 +90,92 @@ async fn main() { } ``` +## Example (Cluster) + +```rust +use std::env; +use deadpool_redis::{redis::{cmd, FromRedisValue}}; +use deadpool_redis::cluster::{Config, Runtime}; + +#[tokio::main] +async fn main() { + let redis_urls = env::var("REDIS_CLUSTER__URLS") + .unwrap() + .split(',') + .map(String::from) + .collect::>(); + let mut cfg = Config::from_urls(redis_urls); + let pool = cfg.create_pool(Some(Runtime::Tokio1)).unwrap(); + { + let mut conn = pool.get().await.unwrap(); + cmd("SET") + .arg(&["deadpool/test_key", "42"]) + .query_async::<_, ()>(&mut conn) + .await.unwrap(); + } + { + let mut conn = pool.get().await.unwrap(); + let value: String = cmd("GET") + .arg(&["deadpool/test_key"]) + .query_async(&mut conn) + .await.unwrap(); + assert_eq!(value, "42".to_string()); + } +} +``` + +### Example with `config` and `dotenv` crate + +```rust +use deadpool_redis::redis::{cmd, FromRedisValue}, +use deadpool_redis::cluster::{Runtime}; +use dotenv::dotenv; +# use serde_1 as serde; + +#[derive(Debug, serde::Deserialize)] +# #[serde(crate = "serde_1")] +struct Config { + #[serde(default)] + redis_cluster: deadpool_redis::cluster::Config +} + +impl Config { + pub fn from_env() -> Result { + config::Config::builder() + .add_source( + config::Environment::default() + .separator("__") + .try_parsing(true) + .list_separator(","), + ) + .build()? + .try_deserialize() + } +} + +#[tokio::main] +async fn main() { + dotenv().ok(); + let cfg = Config::from_env().unwrap(); + let pool = cfg.redis_cluster.create_pool(Some(Runtime::Tokio1)).unwrap(); + { + let mut conn = pool.get().await.unwrap(); + cmd("SET") + .arg(&["deadpool/test_key", "42"]) + .query_async::<_, ()>(&mut conn) + .await.unwrap(); + } + { + let mut conn = pool.get().await.unwrap(); + let value: String = cmd("GET") + .arg(&["deadpool/test_key"]) + .query_async(&mut conn) + .await.unwrap(); + assert_eq!(value, "42".to_string()); + } +} +``` + ## FAQ - **How can I enable features of the `redis` crate?** diff --git a/redis-cluster/src/config.rs b/redis/src/cluster/config.rs similarity index 97% rename from redis-cluster/src/config.rs rename to redis/src/cluster/config.rs index 6339a630..9946c643 100644 --- a/redis-cluster/src/config.rs +++ b/redis/src/cluster/config.rs @@ -4,7 +4,7 @@ use redis::RedisError; #[cfg(feature = "serde")] use serde_1::{Deserialize, Serialize}; -use crate::{CreatePoolError, Pool, PoolBuilder, PoolConfig, RedisResult, Runtime}; +use super::{CreatePoolError, Pool, PoolBuilder, PoolConfig, RedisResult, Runtime}; /// Configuration object. /// @@ -79,10 +79,10 @@ impl Config { pub fn builder(&self) -> Result { let manager = match (&self.urls, &self.connections) { (Some(urls), None) => { - crate::Manager::new(urls.iter().map(|url| url.as_str()).collect())? + super::Manager::new(urls.iter().map(|url| url.as_str()).collect())? } - (None, Some(connections)) => crate::Manager::new(connections.clone())?, - (None, None) => crate::Manager::new(vec![ConnectionInfo::default()])?, + (None, Some(connections)) => super::Manager::new(connections.clone())?, + (None, None) => super::Manager::new(vec![ConnectionInfo::default()])?, (Some(_), Some(_)) => return Err(ConfigError::UrlAndConnectionSpecified), }; let pool_config = self.get_pool_config(); diff --git a/redis-cluster/src/lib.rs b/redis/src/cluster/mod.rs similarity index 72% rename from redis-cluster/src/lib.rs rename to redis/src/cluster/mod.rs index 29b35eff..b28a3923 100644 --- a/redis-cluster/src/lib.rs +++ b/redis/src/cluster/mod.rs @@ -1,4 +1,3 @@ -#![doc = include_str!("../README.md")] #![cfg_attr(docsrs, feature(doc_cfg))] #![deny( nonstandard_style, @@ -31,8 +30,9 @@ use std::{ use deadpool::{async_trait, managed}; use redis::{aio::ConnectionLike, IntoConnectionInfo, RedisError, RedisResult}; -pub use redis; -pub use redis_cluster_async::{Client, Connection as RedisConnection}; +use redis; +pub use redis::cluster::ClusterClient; +pub use redis::cluster_async::ClusterConnection; pub use self::config::{Config, ConfigError}; @@ -47,11 +47,11 @@ deadpool::managed_reexports!( type RecycleResult = managed::RecycleResult; -/// Wrapper around [`redis_cluster_async::Connection`]. +/// Wrapper around [`redis::cluster_async::ClusterConnection`]. /// /// This structure implements [`redis::aio::ConnectionLike`] and can therefore -/// be used just like a regular [`redis_cluster_async::Connection`]. -#[allow(missing_debug_implementations)] // `redis_cluster_async::Connection: !Debug` +/// be used just like a regular [`redis::cluster_async::ClusterConnection`]. +#[allow(missing_debug_implementations)] // `redis::cluster_async::ClusterConnection: !Debug` pub struct Connection { conn: Object, } @@ -61,7 +61,7 @@ impl Connection { /// /// This reduces the size of the [`Pool`]. #[must_use] - pub fn take(this: Self) -> RedisConnection { + pub fn take(this: Self) -> ClusterConnection { Object::take(this.conn) } } @@ -73,27 +73,27 @@ impl From for Connection { } impl Deref for Connection { - type Target = RedisConnection; + type Target = ClusterConnection; - fn deref(&self) -> &RedisConnection { + fn deref(&self) -> &ClusterConnection { &self.conn } } impl DerefMut for Connection { - fn deref_mut(&mut self) -> &mut RedisConnection { + fn deref_mut(&mut self) -> &mut ClusterConnection { &mut self.conn } } -impl AsRef for Connection { - fn as_ref(&self) -> &RedisConnection { +impl AsRef for Connection { + fn as_ref(&self) -> &ClusterConnection { &self.conn } } -impl AsMut for Connection { - fn as_mut(&mut self) -> &mut RedisConnection { +impl AsMut for Connection { + fn as_mut(&mut self) -> &mut ClusterConnection { &mut self.conn } } @@ -120,15 +120,15 @@ impl ConnectionLike for Connection { } } -/// [`Manager`] for creating and recycling [`redis_cluster_async`] connections. +/// [`Manager`] for creating and recycling [`redis::cluster_async`] connections. /// /// [`Manager`]: managed::Manager pub struct Manager { - client: Client, + client: ClusterClient, ping_number: AtomicUsize, } -// `redis_cluster_async::Client: !Debug` +// `redis::cluster_async::ClusterClient: !Debug` impl std::fmt::Debug for Manager { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Manager") @@ -143,10 +143,10 @@ impl Manager { /// /// # Errors /// - /// If establishing a new [`Client`] fails. + /// If establishing a new [`ClusterClient`] fails. pub fn new(params: Vec) -> RedisResult { Ok(Self { - client: Client::open(params)?, + client: ClusterClient::new(params)?, ping_number: AtomicUsize::new(0), }) } @@ -154,15 +154,15 @@ impl Manager { #[async_trait] impl managed::Manager for Manager { - type Type = RedisConnection; + type Type = ClusterConnection; type Error = RedisError; - async fn create(&self) -> Result { - let conn = self.client.get_connection().await?; + async fn create(&self) -> Result { + let conn = self.client.get_async_connection().await?; Ok(conn) } - async fn recycle(&self, conn: &mut RedisConnection, _: &Metrics) -> RecycleResult { + async fn recycle(&self, conn: &mut ClusterConnection, _: &Metrics) -> RecycleResult { let ping_number = self.ping_number.fetch_add(1, Ordering::Relaxed).to_string(); let n = redis::cmd("PING") .arg(&ping_number) diff --git a/redis/src/lib.rs b/redis/src/lib.rs index 7305b0d3..e9531088 100644 --- a/redis/src/lib.rs +++ b/redis/src/lib.rs @@ -21,6 +21,8 @@ )] #![allow(clippy::uninlined_format_args)] +#[cfg(feature = "cluster")] +pub mod cluster; mod config; use std::{ diff --git a/redis-cluster/tests/redis.rs b/redis/tests/redis_cluster.rs similarity index 92% rename from redis-cluster/tests/redis.rs rename to redis/tests/redis_cluster.rs index f0fe0a44..cd6b8491 100644 --- a/redis-cluster/tests/redis.rs +++ b/redis/tests/redis_cluster.rs @@ -1,6 +1,6 @@ #![cfg(feature = "serde")] -use deadpool_redis_cluster::Runtime; +use deadpool_redis::cluster::Runtime; use futures::FutureExt; use redis::cmd; use serde_1::{Deserialize, Serialize}; @@ -9,7 +9,7 @@ use serde_1::{Deserialize, Serialize}; #[serde(crate = "serde_1")] struct Config { #[serde(default)] - redis_cluster: deadpool_redis_cluster::Config, + redis_cluster: deadpool_redis::cluster::Config, } impl Config { @@ -28,7 +28,7 @@ impl Config { } } -fn create_pool() -> deadpool_redis_cluster::Pool { +fn create_pool() -> deadpool_redis::cluster::Pool { let cfg = Config::from_env(); cfg.redis_cluster .create_pool(Some(Runtime::Tokio1)) @@ -37,7 +37,7 @@ fn create_pool() -> deadpool_redis_cluster::Pool { #[tokio::test] async fn test_pipeline() { - use deadpool_redis_cluster::redis::pipe; + use deadpool_redis::cluster::redis::pipe; let pool = create_pool(); let mut conn = pool.get().await.unwrap(); let (value,): (String,) = pipe() @@ -55,7 +55,7 @@ async fn test_pipeline() { #[tokio::test] async fn test_high_level_commands() { - use deadpool_redis_cluster::redis::AsyncCommands; + use deadpool_redis::redis::AsyncCommands; let pool = create_pool(); let mut conn = pool.get().await.unwrap(); let _: () = conn.set("deadpool/hlc_test_key", 42).await.unwrap(); diff --git a/test-build.sh b/test-build.sh index bc1b0978..5cf9b71e 100755 --- a/test-build.sh +++ b/test-build.sh @@ -24,13 +24,8 @@ cargo build --no-default-features --features managed,unmanaged cargo build cargo build --no-default-features --features rt_tokio_1 cargo build --no-default-features --features rt_async-std_1 -) - -( - cd redis-cluster - cargo build - cargo build --no-default-features --features rt_tokio_1 - cargo build --no-default-features --features rt_async-std_1 + cargo build --no-default-features --features rt_tokio_1 cluster + cargo build --no-default-features --features rt_async-std_1 cluster ) (