Skip to content

Commit

Permalink
redis: restruct dirs
Browse files Browse the repository at this point in the history
  • Loading branch information
topenkoff committed Aug 9, 2023
1 parent 7b1d0c7 commit e747d88
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 374 deletions.
2 changes: 1 addition & 1 deletion examples/examples/redis.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use axum::{extract::Path, routing::get, Json, Router};

use hitbox_redis::fred::Builder;
use hitbox_redis::Builder;
use hitbox_tower::Cache;
use http::StatusCode;
use tower::ServiceBuilder;
Expand Down
2 changes: 0 additions & 2 deletions hitbox-redis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ keywords = ["cache", "async", "cache-backend", "hitbox", "redis"]

[dependencies]
hitbox-backend = { path = "../hitbox-backend", version = "0.1.0" }
log = "0.4"
redis = { version = "0.22", features = ["tokio-comp", "connection-manager"] }
thiserror = "1"
async-trait = "0.1"
serde = "1"
Expand Down
32 changes: 9 additions & 23 deletions hitbox-redis/src/fred/backend.rs → hitbox-redis/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![allow(missing_docs)]

use std::future::Future;
use std::marker::PhantomData;

Expand All @@ -9,22 +7,12 @@ use fred::{
interfaces::{ClientLike, KeysInterface},
types::{Expiration, FromRedis, RedisKey, RedisValue},
};
use serde::Serialize;

use hitbox_backend::{
serializer::Serializer, BackendError, BackendResult, CacheBackend, CacheableResponse,
CachedValue, DeleteStatus,
};

#[derive(Debug, thiserror::Error)]
pub enum RedisBackendError {
#[error(transparent)]
Fred(#[from] fred::error::RedisError),
#[error(transparent)]
Tokio(#[from] tokio::task::JoinError),
#[error("Setup buidler error: {0}")]
Builder(String),
}
use crate::error::Error;

#[derive(Clone)]
pub struct RedisBackend<S> {
Expand All @@ -33,10 +21,10 @@ pub struct RedisBackend<S> {
}

impl<S> RedisBackend<S> {
async fn execute<'a, T, Fut, F>(&'a self, f: F) -> Result<T, RedisBackendError>
async fn execute<'a, T, Fut, F>(&'a self, f: F) -> Result<T, Error>
where
F: FnOnce(&'a RedisClient) -> Fut,
Fut: Future<Output = Result<T, RedisBackendError>>,
Fut: Future<Output = Result<T, Error>>,
T: Send,
{
let connection_task = self.client.connect();
Expand Down Expand Up @@ -68,10 +56,9 @@ where
client
.get::<Option<S::Raw>, _>(key)
.await
.map_err(RedisBackendError::from)
.map_err(Error::from)
})
.await
.map_err(crate::error::Error::from)
.map_err(BackendError::from)?;
result
.map(|value| S::deserialize(value).map_err(BackendError::from))
Expand All @@ -86,7 +73,7 @@ where
) -> BackendResult<()>
where
T: CacheableResponse + Send,
<T as CacheableResponse>::Cached: Serialize + Send + Sync,
<T as CacheableResponse>::Cached: serde::Serialize + Send + Sync,
{
tracing::debug!("RedisBackend::set::{}", &key);
let key = RedisKey::from(key);
Expand All @@ -96,15 +83,14 @@ where
client
.set::<(), _, S::Raw>(key, ser_value, expire, None, false)
.await
.map_err(RedisBackendError::from)
.map_err(Error::from)
})
.await
.map_err(crate::error::Error::from)
.map_err(BackendError::from)
}

async fn delete(&self, key: String) -> BackendResult<DeleteStatus> {
tracing::debug!("RedisBackend::::{}", &key);
tracing::debug!("RedisBackend::delete::{}", &key);
let key = RedisKey::from(key);
self.execute(|client| async move {
client
Expand All @@ -117,14 +103,14 @@ where
DeleteStatus::Missing
}
})
.map_err(RedisBackendError::from)
.map_err(Error::from)
})
.await
.map_err(crate::error::Error::from)
.map_err(BackendError::from)
}

async fn start(&self) -> BackendResult<()> {
tracing::debug!("RedisBackend::start");
Ok(())
}
}
32 changes: 32 additions & 0 deletions hitbox-redis/src/builder/cluster.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::marker::PhantomData;

use hitbox_backend::serializer::{JsonSerializer, Serializer};

use crate::backend::RedisBackend;
use crate::error::Error;

struct ClusterNode {}

pub struct Cluster<S = JsonSerializer<String>> {
nodes: Vec<ClusterNode>,
_ser: PhantomData<S>,
}

impl<S> Default for Cluster<S> {
fn default() -> Self {
Self {
nodes: vec![],
_ser: PhantomData,
}
}
}

impl<S> Cluster<S> {
pub fn new() -> Self {
Cluster::default()
}

pub fn build(self) -> Result<RedisBackend<S>, Error> {
unimplemented!()
}
}
23 changes: 23 additions & 0 deletions hitbox-redis/src/builder/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
mod cluster;
mod sentinel;
mod standalone;

use cluster::Cluster;
use sentinel::Sentinel;
use standalone::Standalone;

pub struct Builder;

impl Builder {
pub fn standalone() -> Standalone {
Standalone::default()
}

pub fn sentinel() -> Sentinel {
Sentinel::default()
}

pub fn cluster() -> Cluster {
Cluster::default()
}
}
26 changes: 26 additions & 0 deletions hitbox-redis/src/builder/sentinel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::marker::PhantomData;

use hitbox_backend::serializer::{JsonSerializer, Serializer};

use crate::backend::RedisBackend;
use crate::error::Error;

pub struct Sentinel<S = JsonSerializer<String>> {
_ser: PhantomData<S>,
}

impl<S> Default for Sentinel<S> {
fn default() -> Self {
Self { _ser: PhantomData }
}
}

impl<S> Sentinel<S> {
pub fn new() -> Self {
Sentinel::default()
}

pub fn build(self) -> Result<RedisBackend<S>, Error> {
unimplemented!()
}
}
119 changes: 119 additions & 0 deletions hitbox-redis/src/builder/standalone.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
use std::marker::PhantomData;

use fred::clients::RedisClient;
use fred::types::{Blocking, RedisConfig, RespVersion, ServerConfig};
use hitbox_backend::serializer::{JsonSerializer, Serializer};

use crate::backend::RedisBackend;
use crate::error::Error;

pub struct Standalone<S = JsonSerializer<String>> {
host: Option<String>,
port: Option<u16>,
username: Option<String>,
password: Option<String>,
database: Option<u8>,
_ser: PhantomData<S>,
}

impl<S> Default for Standalone<S> {
fn default() -> Self {
Standalone {
username: None,
password: None,
host: Some("127.0.0.1".to_owned()),
port: Some(6379),
database: None,
_ser: PhantomData,
}
}
}

impl<S: Serializer> Standalone<S> {
pub fn from_url(connection_url: &str) -> Result<Standalone<S>, Error> {
let cfg = RedisConfig::from_url(connection_url)?;
if cfg.server.is_centralized() {
let server = cfg.server.hosts()[0];
Ok(Self {
username: cfg.username,
password: cfg.password,
database: cfg.database,
host: Some(server.host.to_string()),
port: Some(server.port),
_ser: PhantomData,
})
} else {
todo!()
}
}

pub fn set_username(self, value: String) -> Self {
Standalone {
username: Some(value),
..self
}
}

pub fn set_password(self, value: String) -> Self {
Standalone {
password: Some(value),
..self
}
}

pub fn set_host(self, value: String) -> Self {
Standalone {
host: Some(value),
..self
}
}

pub fn set_port(self, value: u16) -> Self {
Standalone {
port: Some(value),
..self
}
}

pub fn set_database(self, value: u8) -> Self {
Standalone {
database: Some(value),
..self
}
}

pub fn with_serializer<S2: Serializer>(self) -> Standalone<S2> {
Standalone {
username: self.username,
password: self.password,
host: self.host,
port: self.port,
database: self.database,
_ser: PhantomData::<S2>,
}
}

pub fn build(self) -> Result<RedisBackend<S>, Error> {
let host = self
.host
.ok_or_else(|| Error::Builder("Please setup host".to_owned()))?;
let port = self
.port
.ok_or_else(|| Error::Builder("Please setup port".to_owned()))?;
let config = RedisConfig {
fail_fast: true,
server: ServerConfig::new_centralized(host, port),
blocking: Blocking::Block,
username: self.username,
password: self.password,
version: RespVersion::RESP2,
database: self.database,
};

let client = RedisClient::new(config, None, None);
Ok(RedisBackend {
client,
_ser: self._ser,
})
}
}
16 changes: 5 additions & 11 deletions hitbox-redis/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@
//!
//! [BackendError]: hitbox_backend::BackendError
use hitbox_backend::BackendError;
use redis::RedisError;

/// Redis backend error declaration.
///
/// Simply, it's just a wrapper for [redis::RedisError].
///
/// [redis::RedisError]: redis::RedisError
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Wrapper for all kinds redis-rs errors.
#[error("Redis backend error: {0}")]
Redis(#[from] RedisError),
#[error("Fred error: {0}")]
Fred(#[from] crate::fred::RedisBackendError),
Redis(#[from] fred::error::RedisError),
#[error("Builder error: {0}")]
Builder(String),
#[error(transparent)]
Tokio(#[from] tokio::task::JoinError),
}

impl From<Error> for BackendError {
Expand Down
Loading

0 comments on commit e747d88

Please sign in to comment.