- add: session-service

- move: redis_cache from database service to utils so it can be reused
- update: redis_cache set function to allow creating a key without a lifetime
- update: services to use the new get_or_generate_service_id function
This commit is contained in:
2024-12-20 14:43:25 -05:00
parent 07e991fbdc
commit 3c1f8c40d6
16 changed files with 291 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
use sqlx::{FromRow, Row};
use crate::redis_cache::{Cache, RedisCache}; // Import RedisCache
use utils::redis_cache::{Cache, RedisCache}; // Import RedisCache
use serde::{Serialize, Deserialize};
use std::sync::Arc;
use tokio::sync::Mutex;

View File

@@ -3,7 +3,7 @@ use database_service::db::Database;
use database_service::grpc::database_service::MyDatabaseService;
use database_service::grpc::user_service_server::UserServiceServer;
use database_service::grpc::character_service_server::CharacterServiceServer;
use database_service::redis_cache::RedisCache;
use utils::redis_cache::RedisCache;
use dotenv::dotenv;
use sqlx::postgres::PgPoolOptions;
use std::env;
@@ -36,7 +36,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let health_check_url = format!("http://{}:{}/health", service_address, health_port);
// Register service with Consul
let service_id = consul_registration::generate_service_id();
let service_id = consul_registration::get_or_generate_service_id();
let tags = vec!["version-1.0".to_string()];
let meta = HashMap::new();
consul_registration::register_service(

View File

@@ -1,93 +0,0 @@
use async_trait::async_trait;
use deadpool_redis::{Config, Pool, Runtime};
use redis::{AsyncCommands, RedisError};
use serde::{Deserialize, Serialize};
#[async_trait]
pub trait Cache {
async fn set<T: Serialize + Send + Sync>(
&self,
key: &String,
value: &T,
ttl: u64,
) -> Result<(), redis::RedisError>;
async fn get<T: for<'de> serde::Deserialize<'de> + Send + Sync>(
&self,
key: &String,
) -> Result<Option<T>, redis::RedisError>;
async fn delete(&mut self, key: &str) -> redis::RedisResult<()>;
}
pub struct RedisCache {
pub pool: Pool,
}
impl RedisCache {
pub fn new(redis_url: &str) -> Self {
let cfg = Config::from_url(redis_url);
let pool = cfg.create_pool(Some(Runtime::Tokio1)).expect("Failed to create Redis pool");
RedisCache { pool }
}
}
#[async_trait]
impl Cache for RedisCache {
async fn set<T: Serialize + Send + Sync>(
&self,
key: &String,
value: &T,
ttl: u64,
) -> Result<(), redis::RedisError> {
let mut conn = self.pool.get().await
.map_err(|err| {
redis::RedisError::from((
redis::ErrorKind::IoError,
"Failed to get Redis connection",
format!("{:?}", err),
))
})?;
let serialized_value = serde_json::to_string(value)
.map_err(|err| RedisError::from((
redis::ErrorKind::IoError,
"Serialization error",
format!("Serialization error: {}", err),
)))?;
conn.set_ex(key, serialized_value, ttl).await
}
async fn get<T: for<'de> Deserialize<'de> + Send + Sync>(&self, key: &String) -> Result<Option<T>, redis::RedisError> {
let mut conn = self.pool.get().await
.map_err(|err| {
redis::RedisError::from((
redis::ErrorKind::IoError,
"Failed to get Redis connection",
format!("{:?}", err),
))
})?;
if let Some(serialized_value) = conn.get::<_, Option<String>>(key).await? {
let deserialized_value = serde_json::from_str(&serialized_value)
.map_err(|err| RedisError::from((
redis::ErrorKind::IoError,
"Deserialization error",
format!("Deserialization error: {}", err),
)))?;
Ok(Some(deserialized_value))
} else {
Ok(None)
}
}
async fn delete(&mut self, key: &str) -> redis::RedisResult<()> {
let mut conn = self.pool.get().await
.map_err(|err| {
redis::RedisError::from((
redis::ErrorKind::IoError,
"Failed to get Redis connection",
format!("{:?}", err),
))
})?;
conn.del(key).await
}
}

View File

@@ -1,5 +1,5 @@
use sqlx::{FromRow, Row};
use crate::redis_cache::{RedisCache, Cache}; // Import RedisCache and Cache Trait
use utils::redis_cache::{RedisCache, Cache}; // Import RedisCache and Cache Trait
use serde::{Serialize, Deserialize};
use std::sync::Arc;
use tokio::sync::Mutex;