mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
fix: Implement persistent caching for config table retrieval (#2044)
Co-authored-by: Nitesh Balla <nitesh.balla@juspay.in> Co-authored-by: Narayan Bhat <48803246+Narayanbhat166@users.noreply.github.com> Co-authored-by: BallaNitesh <126162378+BallaNitesh@users.noreply.github.com>
This commit is contained in:
@ -25,7 +25,7 @@ pub async fn set_config(
|
|||||||
|
|
||||||
pub async fn read_config(store: &dyn StorageInterface, key: &str) -> RouterResponse<api::Config> {
|
pub async fn read_config(store: &dyn StorageInterface, key: &str) -> RouterResponse<api::Config> {
|
||||||
let config = store
|
let config = store
|
||||||
.find_config_by_key_cached(key)
|
.find_config_by_key(key)
|
||||||
.await
|
.await
|
||||||
.to_not_found_response(errors::ApiErrorResponse::ConfigNotFound)?;
|
.to_not_found_response(errors::ApiErrorResponse::ConfigNotFound)?;
|
||||||
Ok(ApplicationResponse::Json(config.foreign_into()))
|
Ok(ApplicationResponse::Json(config.foreign_into()))
|
||||||
@ -36,7 +36,7 @@ pub async fn update_config(
|
|||||||
config_update: &api::ConfigUpdate,
|
config_update: &api::ConfigUpdate,
|
||||||
) -> RouterResponse<api::Config> {
|
) -> RouterResponse<api::Config> {
|
||||||
let config = store
|
let config = store
|
||||||
.update_config_cached(&config_update.key, config_update.foreign_into())
|
.update_config_by_key(&config_update.key, config_update.foreign_into())
|
||||||
.await
|
.await
|
||||||
.to_not_found_response(errors::ApiErrorResponse::ConfigNotFound)?;
|
.to_not_found_response(errors::ApiErrorResponse::ConfigNotFound)?;
|
||||||
Ok(ApplicationResponse::Json(config.foreign_into()))
|
Ok(ApplicationResponse::Json(config.foreign_into()))
|
||||||
|
|||||||
@ -106,7 +106,7 @@ where
|
|||||||
let connector_api_version = if supported_connector.contains(&connector_enum) {
|
let connector_api_version = if supported_connector.contains(&connector_enum) {
|
||||||
state
|
state
|
||||||
.store
|
.store
|
||||||
.find_config_by_key_cached(&format!("connector_api_version_{connector_id}"))
|
.find_config_by_key(&format!("connector_api_version_{connector_id}"))
|
||||||
.await
|
.await
|
||||||
.map(|value| value.config)
|
.map(|value| value.config)
|
||||||
.ok()
|
.ok()
|
||||||
|
|||||||
@ -262,7 +262,7 @@ pub async fn construct_refund_router_data<'a, F>(
|
|||||||
let connector_api_version = if supported_connector.contains(&connector_enum) {
|
let connector_api_version = if supported_connector.contains(&connector_enum) {
|
||||||
state
|
state
|
||||||
.store
|
.store
|
||||||
.find_config_by_key_cached(&format!("connector_api_version_{connector_id}"))
|
.find_config_by_key(&format!("connector_api_version_{connector_id}"))
|
||||||
.await
|
.await
|
||||||
.map(|value| value.config)
|
.map(|value| value.config)
|
||||||
.ok()
|
.ok()
|
||||||
|
|||||||
@ -29,7 +29,7 @@ pub async fn lookup_webhook_event(
|
|||||||
Ok(merchant_webhook_config) => merchant_webhook_config.contains(event),
|
Ok(merchant_webhook_config) => merchant_webhook_config.contains(event),
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
//if failed to fetch from redis. fetch from db and populate redis
|
//if failed to fetch from redis. fetch from db and populate redis
|
||||||
db.find_config_by_key_cached(&redis_key)
|
db.find_config_by_key(&redis_key)
|
||||||
.await
|
.await
|
||||||
.map(|config| {
|
.map(|config| {
|
||||||
if let Ok(set) =
|
if let Ok(set) =
|
||||||
|
|||||||
@ -25,7 +25,7 @@ pub trait ConfigInterface {
|
|||||||
key: &str,
|
key: &str,
|
||||||
) -> CustomResult<storage::Config, errors::StorageError>;
|
) -> CustomResult<storage::Config, errors::StorageError>;
|
||||||
|
|
||||||
async fn find_config_by_key_cached(
|
async fn find_config_by_key_from_db(
|
||||||
&self,
|
&self,
|
||||||
key: &str,
|
key: &str,
|
||||||
) -> CustomResult<storage::Config, errors::StorageError>;
|
) -> CustomResult<storage::Config, errors::StorageError>;
|
||||||
@ -36,12 +36,6 @@ pub trait ConfigInterface {
|
|||||||
config_update: storage::ConfigUpdate,
|
config_update: storage::ConfigUpdate,
|
||||||
) -> CustomResult<storage::Config, errors::StorageError>;
|
) -> CustomResult<storage::Config, errors::StorageError>;
|
||||||
|
|
||||||
async fn update_config_cached(
|
|
||||||
&self,
|
|
||||||
key: &str,
|
|
||||||
config_update: storage::ConfigUpdate,
|
|
||||||
) -> CustomResult<storage::Config, errors::StorageError>;
|
|
||||||
|
|
||||||
async fn delete_config_by_key(&self, key: &str) -> CustomResult<bool, errors::StorageError>;
|
async fn delete_config_by_key(&self, key: &str) -> CustomResult<bool, errors::StorageError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,32 +49,8 @@ impl ConfigInterface for Store {
|
|||||||
config.insert(&conn).await.map_err(Into::into).into_report()
|
config.insert(&conn).await.map_err(Into::into).into_report()
|
||||||
}
|
}
|
||||||
|
|
||||||
//fetch directly from DB
|
|
||||||
async fn find_config_by_key(
|
|
||||||
&self,
|
|
||||||
key: &str,
|
|
||||||
) -> CustomResult<storage::Config, errors::StorageError> {
|
|
||||||
let conn = connection::pg_connection_write(self).await?;
|
|
||||||
storage::Config::find_by_key(&conn, key)
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
.into_report()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_config_by_key(
|
|
||||||
&self,
|
|
||||||
key: &str,
|
|
||||||
config_update: storage::ConfigUpdate,
|
|
||||||
) -> CustomResult<storage::Config, errors::StorageError> {
|
|
||||||
let conn = connection::pg_connection_write(self).await?;
|
|
||||||
storage::Config::update_by_key(&conn, key, config_update)
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
.into_report()
|
|
||||||
}
|
|
||||||
|
|
||||||
//update in DB and remove in redis and cache
|
//update in DB and remove in redis and cache
|
||||||
async fn update_config_cached(
|
async fn update_config_by_key(
|
||||||
&self,
|
&self,
|
||||||
key: &str,
|
key: &str,
|
||||||
config_update: storage::ConfigUpdate,
|
config_update: storage::ConfigUpdate,
|
||||||
@ -91,12 +61,28 @@ impl ConfigInterface for Store {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
//check in cache, then redis then finally DB, and on the way back populate redis and cache
|
async fn find_config_by_key_from_db(
|
||||||
async fn find_config_by_key_cached(
|
|
||||||
&self,
|
&self,
|
||||||
key: &str,
|
key: &str,
|
||||||
) -> CustomResult<storage::Config, errors::StorageError> {
|
) -> CustomResult<storage::Config, errors::StorageError> {
|
||||||
cache::get_or_populate_in_memory(self, key, || self.find_config_by_key(key), &CONFIG_CACHE)
|
let conn = connection::pg_connection_write(self).await?;
|
||||||
|
storage::Config::find_by_key(&conn, key)
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)
|
||||||
|
.into_report()
|
||||||
|
}
|
||||||
|
|
||||||
|
//check in cache, then redis then finally DB, and on the way back populate redis and cache
|
||||||
|
async fn find_config_by_key(
|
||||||
|
&self,
|
||||||
|
key: &str,
|
||||||
|
) -> CustomResult<storage::Config, errors::StorageError> {
|
||||||
|
cache::get_or_populate_in_memory(
|
||||||
|
self,
|
||||||
|
key,
|
||||||
|
|| self.find_config_by_key_from_db(key),
|
||||||
|
&CONFIG_CACHE,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,18 +124,6 @@ impl ConfigInterface for MockDb {
|
|||||||
Ok(config_new)
|
Ok(config_new)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_config_by_key(
|
|
||||||
&self,
|
|
||||||
key: &str,
|
|
||||||
) -> CustomResult<storage::Config, errors::StorageError> {
|
|
||||||
let configs = self.configs.lock().await;
|
|
||||||
let config = configs.iter().find(|c| c.key == key).cloned();
|
|
||||||
|
|
||||||
config.ok_or_else(|| {
|
|
||||||
errors::StorageError::ValueNotFound("cannot find config".to_string()).into()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_config_by_key(
|
async fn update_config_by_key(
|
||||||
&self,
|
&self,
|
||||||
key: &str,
|
key: &str,
|
||||||
@ -174,30 +148,6 @@ impl ConfigInterface for MockDb {
|
|||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
async fn update_config_cached(
|
|
||||||
&self,
|
|
||||||
key: &str,
|
|
||||||
config_update: storage::ConfigUpdate,
|
|
||||||
) -> CustomResult<storage::Config, errors::StorageError> {
|
|
||||||
let result = self
|
|
||||||
.configs
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.iter_mut()
|
|
||||||
.find(|c| c.key == key)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
errors::StorageError::ValueNotFound("cannot find config to update".to_string())
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
.map(|c| {
|
|
||||||
let config_updated =
|
|
||||||
ConfigUpdateInternal::from(config_update).create_config(c.clone());
|
|
||||||
*c = config_updated.clone();
|
|
||||||
config_updated
|
|
||||||
});
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn delete_config_by_key(&self, key: &str) -> CustomResult<bool, errors::StorageError> {
|
async fn delete_config_by_key(&self, key: &str) -> CustomResult<bool, errors::StorageError> {
|
||||||
let mut configs = self.configs.lock().await;
|
let mut configs = self.configs.lock().await;
|
||||||
@ -216,7 +166,19 @@ impl ConfigInterface for MockDb {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_config_by_key_cached(
|
async fn find_config_by_key_from_db(
|
||||||
|
&self,
|
||||||
|
key: &str,
|
||||||
|
) -> CustomResult<storage::Config, errors::StorageError> {
|
||||||
|
let configs = self.configs.lock().await;
|
||||||
|
let config = configs.iter().find(|c| c.key == key).cloned();
|
||||||
|
|
||||||
|
config.ok_or_else(|| {
|
||||||
|
errors::StorageError::ValueNotFound("cannot find config".to_string()).into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn find_config_by_key(
|
||||||
&self,
|
&self,
|
||||||
key: &str,
|
key: &str,
|
||||||
) -> CustomResult<storage::Config, errors::StorageError> {
|
) -> CustomResult<storage::Config, errors::StorageError> {
|
||||||
|
|||||||
@ -124,7 +124,7 @@ pub async fn get_sync_process_schedule_time(
|
|||||||
process_data::ConnectorPTMapping,
|
process_data::ConnectorPTMapping,
|
||||||
errors::StorageError,
|
errors::StorageError,
|
||||||
> = db
|
> = db
|
||||||
.find_config_by_key_cached(&format!("pt_mapping_{connector}"))
|
.find_config_by_key(&format!("pt_mapping_{connector}"))
|
||||||
.await
|
.await
|
||||||
.map(|value| value.config)
|
.map(|value| value.config)
|
||||||
.and_then(|config| {
|
.and_then(|config| {
|
||||||
|
|||||||
Reference in New Issue
Block a user