diff --git a/src/spaceone/cost_analysis/manager/unified_cost_manager.py b/src/spaceone/cost_analysis/manager/unified_cost_manager.py index 30e9857..3e707df 100644 --- a/src/spaceone/cost_analysis/manager/unified_cost_manager.py +++ b/src/spaceone/cost_analysis/manager/unified_cost_manager.py @@ -5,7 +5,7 @@ from dateutil.relativedelta import relativedelta from mongoengine import QuerySet -from spaceone.core import queue, utils, config +from spaceone.core import queue, utils, config, cache from spaceone.core.error import * from spaceone.core.manager import BaseManager @@ -78,24 +78,54 @@ def analyze_yearly_unified_costs(self, query, target="SECONDARY_PREFERRED"): return self.unified_cost_model.analyze(**query) - def analyze_unified_costs_by_granularity(self, query: dict) -> dict: - granularity = query["granularity"] + @cache.cacheable( + key="cost-analysis:analyze-unified-costs:yearly:{query_hash}", expire=3600 * 24 + ) + def analyze_unified_yearly_costs_with_cache(self, query: dict) -> dict: + return self.analyze_unified_costs(query) + + @cache.cacheable( + key="cost-analysis:analyze-unified-costs:monthly:{domain_id}:{query_hash}", + expire=3600 * 24, + ) + def analyze_unified_monthly_costs_with_cache( + self, query: dict, query_hash: str, domain_id: str + ) -> dict: + return self.analyze_unified_costs(query) + + def analyze_unified_costs_by_granularity(self, query: dict, domain_id: str) -> dict: + self._check_unified_cost_data_range(query) + granularity = query["granularity"] + + # Save query history to speed up data loading + query_hash: str = utils.dict_to_hash(query) if granularity == "DAILY": raise ERROR_INVALID_PARAMETER( key="query.granularity", reason=f"{granularity} is not supported" ) elif granularity == "MONTHLY": - response = self.analyze_unified_costs(query) + response = self.analyze_unified_monthly_costs_with_cache( + query, query_hash, domain_id + ) else: - response = self.analyze_yearly_unified_costs(query) + response = self.analyze_unified_yearly_costs_with_cache( + query, query_hash, domain_id + ) return response def stat_unified_costs(self, query) -> dict: return self.unified_cost_model.stat(**query) + @staticmethod + def remove_stat_cache(domain_id: str): + cache.delete_pattern(f"cost-analysis:analyze-unified-costs:*:{domain_id}:*") + cache.delete_pattern(f"cost-analysis:stat-unified-costs:*:{domain_id}:*") + + _LOGGER.debug(f"[remove_stat_cache] domain_id: {domain_id}") + @staticmethod def push_unified_cost_job_task(params: dict) -> None: token = config.get_global("TOKEN") diff --git a/src/spaceone/cost_analysis/service/unified_cost_service.py b/src/spaceone/cost_analysis/service/unified_cost_service.py index 01969e8..89fc973 100644 --- a/src/spaceone/cost_analysis/service/unified_cost_service.py +++ b/src/spaceone/cost_analysis/service/unified_cost_service.py @@ -83,8 +83,8 @@ def run_unified_cost_by_scheduler(self, params: dict) -> None: exc_info=True, ) - # @transaction(exclude=["authenticate", "authorization", "mutation"]) - def run_unified_cost(self, params: dict): + @transaction(exclude=["authenticate", "authorization", "mutation"]) + def run_unified_cost(self, params: dict) -> None: """ Args: params (dict): { @@ -94,11 +94,6 @@ def run_unified_cost(self, params: dict): "exchange_date": 'str' (optional) } """ - - from spaceone.core import model - - model.init_all(False) - domain_id = params["domain_id"] aggregation_month = params.get("month") exchange_date = params.get("exchange_date") @@ -167,6 +162,8 @@ def run_unified_cost(self, params: dict): self.unified_cost_job_mgr.update_is_confirmed_unified_cost_job( unified_cost_job_vo, is_confirmed ) + + self.unified_cost_mgr.remove_stat_cache(domain_id) except Exception as e: _LOGGER.error(f"[run_unified_cost] error: {e}", exc_info=True) self.unified_cost_job_mgr.update_is_confirmed_unified_cost_job( @@ -332,8 +329,11 @@ def analyze(self, params: UnifiedCostAnalyzeQueryRequest) -> dict: """ query = params.query or {} + domain_id = params.domain_id - return self.unified_cost_mgr.analyze_unified_costs_by_granularity(query) + return self.unified_cost_mgr.analyze_unified_costs_by_granularity( + query, domain_id + ) @transaction( permission="cost-analysis:UnifiedCost.read",