diff --git a/Cargo.lock b/Cargo.lock index c6ba96e683..52ef14933f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,7 @@ dependencies = [ "parse-display", "pretty_assertions", "rand", + "redis", "regex", "schemars", "sea-orm", @@ -524,6 +525,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1858,6 +1869,21 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redis" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6472825949c09872e8f2c50bde59fcefc17748b6be5c90fd67cd8b4daca73bfd" +dependencies = [ + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1_smol", + "socket2", + "url", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -2295,6 +2321,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "sha2" version = "0.10.8" diff --git a/Cargo.toml b/Cargo.toml index 7ca43c960b..b82635d8b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ pretty_assertions = "1.4.0" proc-macro2 = "1.0.79" quote = "1.0.36" rand = "0.8.5" +redis = "0.25.3" regex = "1.10.4" schemars = "0.8.16" sea-orm = "0.12.15" diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml index af9e10cdc1..d077028e13 100644 --- a/packages/backend-rs/Cargo.toml +++ b/packages/backend-rs/Cargo.toml @@ -30,6 +30,7 @@ jsonschema = { workspace = true } once_cell = { workspace = true } parse-display = { workspace = true } rand = { workspace = true } +redis = { workspace = true } regex = { workspace = true } schemars = { workspace = true, features = ["chrono"] } sea-orm = { workspace = true, features = ["sqlx-postgres", "runtime-tokio-rustls"] } diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index d985eb368d..433e80999c 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -29,7 +29,7 @@ export interface ServerConfig { /** `NapiValue` is not implemented for `u64` */ maxFileSize?: number accessLog?: string - clusterLimits?: _WorkerConfig + clusterLimits?: WorkerConfigInternal cuid?: IdConfig outgoingAddress?: string deliverJobConcurrency?: number @@ -80,7 +80,7 @@ export interface WorkerConfig { web: number queue: number } -export interface WorkerConfig { +export interface WorkerConfigInternal { web?: number queue?: number } diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index 4b9fbc7131..edfdf6109c 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -25,7 +25,7 @@ struct ServerConfig { /// `NapiValue` is not implemented for `u64` pub max_file_size: Option<i64>, pub access_log: Option<String>, - pub cluster_limits: Option<_WorkerConfig>, + pub cluster_limits: Option<WorkerConfigInternal>, pub cuid: Option<IdConfig>, pub outgoing_address: Option<String>, @@ -103,7 +103,7 @@ pub struct WorkerConfig { #[derive(Clone, Debug, PartialEq, Deserialize)] #[serde(rename_all = "camelCase")] #[crate::export(object, use_nullable = false)] -pub struct _WorkerConfig { +pub struct WorkerConfigInternal { pub web: Option<u32>, pub queue: Option<u32>, } diff --git a/packages/backend-rs/src/database/mod.rs b/packages/backend-rs/src/database/mod.rs index 26db81c644..7a6277068b 100644 --- a/packages/backend-rs/src/database/mod.rs +++ b/packages/backend-rs/src/database/mod.rs @@ -1,2 +1,6 @@ pub use postgresql::db_conn; +pub use redis::key as redis_key; +pub use redis::redis_conn; + pub mod postgresql; +pub mod redis; diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs new file mode 100644 index 0000000000..863f57b35d --- /dev/null +++ b/packages/backend-rs/src/database/redis.rs @@ -0,0 +1,47 @@ +use crate::config::server::CONFIG; +use redis::{Client, Connection, RedisError}; + +static REDIS_CLIENT: once_cell::sync::OnceCell<Client> = once_cell::sync::OnceCell::new(); + +fn init_redis() -> Result<Client, RedisError> { + let redis_url = { + let mut params = vec!["redis://".to_owned()]; + + if let Some(user) = &CONFIG.redis.user { + params.push(user.to_string()) + } + if let Some(pass) = &CONFIG.redis.pass { + params.push(format!(":{}@", pass)) + } + params.push(CONFIG.redis.host.to_string()); + params.push(format!(":{}", CONFIG.redis.port)); + params.push(format!("/{}", CONFIG.redis.db)); + + params.concat() + }; + + Client::open(redis_url) +} + +pub fn redis_conn() -> Result<Connection, RedisError> { + match REDIS_CLIENT.get() { + Some(client) => Ok(client.get_connection()?), + None => init_redis()?.get_connection(), + } +} + +#[inline] +/// prefix redis key with the hostname +pub fn key(key: &str) -> String { + format!("{}:{}", CONFIG.hostname, key) +} + +#[cfg(test)] +mod unit_test { + use super::init_redis; + + #[test] + fn connect_test() { + assert!(init_redis().is_ok()); + } +}