Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add redis backend #813

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 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
84 changes: 69 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ autoconnect_settings = { path = "./autoconnect/autoconnect-settings" }
autoconnect_web = { path = "./autoconnect/autoconnect-web" }
autoconnect_ws = { path = "./autoconnect/autoconnect-ws" }
autoconnect_ws_clientsm = { path = "./autoconnect/autoconnect-ws/autoconnect-ws-clientsm" }
autopush_common = { path = "./autopush-common", features = ["bigtable"] }
autopush_common = { path = "./autopush-common" }

[profile.release]
debug = 1
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# RUST_VER
FROM rust:1.81-bookworm AS builder
ARG CRATE
ARG BUILD_ARGS

ADD . /app
WORKDIR /app
Expand All @@ -16,7 +17,7 @@ RUN \
cargo --version && \
rustc --version && \
mkdir -m 755 bin && \
cargo install --path $CRATE --locked --root /app
cargo install --path $CRATE $BUILD_ARGS --locked --root /app


FROM debian:bookworm-slim
Expand Down
1 change: 1 addition & 0 deletions autoconnect/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ docopt = "1.1"
default = ["bigtable"]
bigtable = ["autopush_common/bigtable", "autoconnect_settings/bigtable"]
emulator = ["bigtable"]
redis = ["autopush_common/redis", "autoconnect_settings/redis"]
log_vapid = []
1 change: 1 addition & 0 deletions autoconnect/autoconnect-settings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ autopush_common.workspace = true
# specify the default via the calling crate, in order to simplify default chains.
bigtable = ["autopush_common/bigtable"]
emulator = ["bigtable"]
redis = ["autopush_common/redis"]
7 changes: 7 additions & 0 deletions autoconnect/autoconnect-settings/src/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use std::{sync::Arc, time::Duration};

#[cfg(feature = "bigtable")]
use autopush_common::db::bigtable::BigTableClientImpl;
#[cfg(feature = "redis")]
use autopush_common::db::redis::RedisClientImpl;
use cadence::StatsdClient;
use config::ConfigError;
use fernet::{Fernet, MultiFernet};
Expand Down Expand Up @@ -78,6 +80,11 @@ impl AppState {
client.spawn_sweeper(Duration::from_secs(30));
Box::new(client)
}
#[cfg(feature = "redis")]
StorageType::Redis => Box::new(
RedisClientImpl::new(metrics.clone(), &db_settings)
.map_err(|e| ConfigError::Message(e.to_string()))?,
),
_ => panic!(
"Invalid Storage type {:?}. Check {}__DB_DSN.",
storage_type,
Expand Down
13 changes: 12 additions & 1 deletion autoconnect/autoconnect-settings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use config::{Config, ConfigError, Environment, File};
use fernet::Fernet;
use lazy_static::lazy_static;
use serde::{Deserialize, Deserializer};
use serde_json::json;

use autopush_common::util::deserialize_u32_to_duration;

Expand Down Expand Up @@ -218,6 +217,7 @@ impl Settings {
Ok(())
}

#[cfg(feature = "bigtable")]
pub fn test_settings() -> Self {
let db_dsn = Some("grpc://localhost:8086".to_string());
// BigTable DB_SETTINGS.
Expand All @@ -234,6 +234,17 @@ impl Settings {
..Default::default()
}
}

#[cfg(all(feature = "redis", not(feature = "bigtable")))]
pub fn test_settings() -> Self {
let db_dsn = Some("redis://localhost".to_string());
let db_settings = "".to_string();
Self {
db_dsn,
db_settings,
..Default::default()
}
}
}

fn deserialize_f64_to_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>
Expand Down
2 changes: 2 additions & 0 deletions autoendpoint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ bigtable = ["autopush_common/bigtable"]
# enable emulator to call locally run data store.
emulator = ["bigtable"]

redis = ["autopush_common/redis"]

# Enable "stub" router for local testing purposes.
# The "stub" will return specified error strings or success
# depending on which `app_id` client is called based on the registration
Expand Down
4 changes: 4 additions & 0 deletions autoendpoint/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use serde_json::json;

#[cfg(feature = "bigtable")]
use autopush_common::db::bigtable::BigTableClientImpl;
#[cfg(feature = "redis")]
use autopush_common::db::redis::RedisClientImpl;
use autopush_common::{
db::{client::DbClient, spawn_pool_periodic_reporter, DbSettings, StorageType},
middleware::sentry::SentryWrapper,
Expand Down Expand Up @@ -77,6 +79,8 @@ impl Server {
client.spawn_sweeper(Duration::from_secs(30));
Box::new(client)
}
#[cfg(feature = "redis")]
StorageType::Redis => Box::new(RedisClientImpl::new(metrics.clone(), &db_settings)?),
_ => {
debug!("No idea what {:?} is", &db_settings.dsn);
return Err(ApiErrorKind::General(
Expand Down
2 changes: 2 additions & 0 deletions autopush-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ grpcio = { version = "=0.13.0", features = ["openssl"], optional = true }
grpcio-sys = { version = "=0.13.0", optional = true }
protobuf = { version = "=2.28.0", optional = true } # grpcio does not support protobuf 3+
form_urlencoded = { version = "1.2", optional = true }
redis = { version = "0.27.6", features = ["aio", "tokio-comp"]}

[dev-dependencies]
mockito = "0.31"
Expand All @@ -80,3 +81,4 @@ bigtable = [
emulator = [
"bigtable",
] # used for testing big table, requires an external bigtable emulator running.
redis = []
4 changes: 2 additions & 2 deletions autopush-common/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub fn main() {
if !cfg!(feature = "bigtable") {
panic!("No database defined! Please compile with `features=bigtable`");
if !cfg!(feature = "bigtable") && !cfg!(feature = "redis") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bigtable and redis are conflicting feature flags, no?

If you like, we do a conditional check in syncstorage-rs to prevent folk from accidentally specifying both flags.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They should not be conflicting, the server is selected with the dsn url

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the actual database selection is non-conflicting, but the compilation is not. I don't know of a situation where someone might want to have both Bigtable and Redis support enabled on the back end at the same time, considering that there's only one database you can specify or use.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree there is no use case when both are used, but I can see some examples for compiling both. For instance if a generic container image is published/used, or one do a build that can be used in different environments, (dev/tests with redis, integration/prod with bigtable)

panic!("No database defined! Please compile with `features=bigtable` (or redis)");
}
}
4 changes: 4 additions & 0 deletions autopush-common/src/db/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ pub enum DbError {
#[error("BigTable error: {0}")]
BTError(#[from] BigTableError),

#[cfg(feature = "redis")]
#[error("Redis error {0}")]
RedisError(#[from] redis::RedisError),

#[error("Connection failure: {0}")]
ConnectionError(String),

Expand Down
13 changes: 13 additions & 0 deletions autopush-common/src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub mod bigtable;
pub mod client;
pub mod error;
pub mod models;
#[cfg(feature = "redis")]
pub mod redis;
pub mod reporter;
pub mod routing;

Expand All @@ -45,13 +47,17 @@ pub enum StorageType {
INVALID,
#[cfg(feature = "bigtable")]
BigTable,
#[cfg(feature = "redis")]
Redis,
}

impl From<&str> for StorageType {
fn from(name: &str) -> Self {
match name.to_lowercase().as_str() {
#[cfg(feature = "bigtable")]
"bigtable" => Self::BigTable,
#[cfg(feature = "redis")]
"redis" => Self::Redis,
_ => Self::INVALID,
}
}
Expand All @@ -65,6 +71,8 @@ impl StorageType {
let mut result: Vec<&str> = Vec::new();
#[cfg(feature = "bigtable")]
result.push("Bigtable");
#[cfg(feature = "redis")]
result.push("Redis");
result
}

Expand All @@ -90,6 +98,11 @@ impl StorageType {
}
return Self::BigTable;
}
#[cfg(feature = "redis")]
if dsn.starts_with("redis") {
trace!("Found redis");
return Self::Redis;
}
Self::INVALID
}
}
Expand Down
Loading