From d6bd8fdee0f83d102b104666a8d69f2b4481f2fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=20=E6=9F=8F?= Date: Tue, 10 Dec 2024 15:46:40 +0900 Subject: [PATCH] add cache function --- backend/app/api/api_v1/routers/platform.py | 65 +++++++++++----------- backend/app/core/__init__.py | 1 + backend/app/core/cache.py | 55 ++++++++++++++++++ backend/app/db/cruddb/dbapp.py | 2 +- backend/app/tests/test_domain.py | 6 +- backend/app/tests/test_user_app.py | 3 +- 6 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 backend/app/core/cache.py diff --git a/backend/app/api/api_v1/routers/platform.py b/backend/app/api/api_v1/routers/platform.py index c6dac46..3e9d218 100644 --- a/backend/app/api/api_v1/routers/platform.py +++ b/backend/app/api/api_v1/routers/platform.py @@ -15,6 +15,7 @@ from app.db.cruddb import domainService,appService import httpx import app.core.config as config +from app.core import domainCacheService platform_router = r = APIRouter() @@ -82,10 +83,10 @@ async def apps_update( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) + if not domainurl: return ApiReturnModel(data = None) - return ApiReturnModel(data =appService.update_appversion(db, domain.url,app,user.id)) + return ApiReturnModel(data =appService.update_appversion(db, domainurl,app,user.id)) except Exception as e: raise APIException('platform:apps',request.url._url,f"Error occurred while get create app :",e) @@ -100,10 +101,10 @@ async def apps_delete( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) #get_activedomain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) #get_activedomain(db, user.id) + if not domainurl: return ApiReturnModel(data = None) - return ApiReturnModel(data =appService.delete_app(db, domain.url,appid)) + return ApiReturnModel(data =appService.delete_app(db, domainurl,appid)) except Exception as e: raise APIException('platform:apps',request.url._url,f"Error occurred while delete app({appid}):",e) @@ -119,10 +120,10 @@ async def appversions_list( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) #get_activedomain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) #get_activedomain(db, user.id) + if not domainurl: return ApiReturnPage(data = None) - return appService.get_appversions(db,domain.url,appid) + return appService.get_appversions(db,domainurl,appid) except Exception as e: raise APIException('platform:appversions',request.url._url,f"Error occurred while get app({appid}) version :",e) @@ -139,10 +140,10 @@ async def appversions_change( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) #get_activedomain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) #get_activedomain(db, user.id) + if not domainurl: ApiReturnModel(data = None) - return ApiReturnModel(data = appService.change_appversion(db, domain.url,appid,version,user.id)) + return ApiReturnModel(data = appService.change_appversion(db, domainurl,appid,version,user.id)) except Exception as e: raise APIException('platform:appversions',request.url._url,f"Error occurred while change app version:",e) @@ -237,7 +238,7 @@ async def action_data( @r.get( "/flow/{appid}",tags=["App"], - response_model=ApiReturnModel[List[Flow|None]], + response_model=ApiReturnModel[Flow|None], response_model_exclude_none=True, ) async def flow_details( @@ -247,10 +248,10 @@ async def flow_details( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) + if not domainurl: return ApiReturnModel(data = None) - return ApiReturnModel(data = appService.get_flow(db, domain.url, appid,user.id)) + return ApiReturnModel(data = appService.get_flow(db, domainurl, appid,user.id)) except Exception as e: raise APIException('platform:flow',request.url._url,f"Error occurred while get flow by flowid:",e) @@ -266,11 +267,10 @@ async def flow_list( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) #get_activedomain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) #get_activedomain(db, user.id) + if not domainurl: return [] - print("domain=>",domain) - flows = get_flows_by_app(db, domain.url, appid) + flows = get_flows_by_app(db, domainurl, appid) return flows except Exception as e: raise APIException('platform:flow',request.url._url,f"Error occurred while get flow by appid:",e) @@ -286,10 +286,10 @@ async def flow_create( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) #get_activedomain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) #get_activedomain(db, user.id) + if not domainurl: return ApiReturnModel(data = None) - return ApiReturnModel(data = appService.create_flow(db, domain.url, flow,user.id)) + return ApiReturnModel(data = appService.create_flow(db, domainurl, flow,user.id)) except Exception as e: raise APIException('platform:flow',request.url._url,f"Error occurred while create flow:",e) @@ -306,10 +306,10 @@ async def flow_edit( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) + if not domainurl: return ApiReturnModel(data = None) - return ApiReturnModel(data = appService.edit_flow(db,domain.url, flow,user.id)) + return ApiReturnModel(data = appService.edit_flow(db,domainurl, flow,user.id)) except Exception as e: raise APIException('platform:flow',request.url._url,f"Error occurred while edit flow:",e) @@ -326,8 +326,8 @@ async def flow_delete( db=Depends(get_db), ): try: - domain = domainService.get_default_domain(db, user.id) - if not domain: + domainurl = domainCacheService.get_default_domainurl(db,user.id) + if not domainurl: return ApiReturnModel(data = None) return ApiReturnModel(data = appService.delete_flow(db, flowid)) except Exception as e: @@ -395,7 +395,10 @@ async def domain_edit( db=Depends(get_db), ): try: - return ApiReturnModel(data = domainService.edit_domain(db, domain,user.id)) + domain = domainService.edit_domain(db, domain,user.id) + if domain : + domainCacheService.clear_default_domainurl() + return ApiReturnModel(data = domain) except Exception as e: raise APIException('platform:domain',request.url._url,f"Error occurred while edit domain:",e) @@ -482,7 +485,7 @@ async def get_defaultuserdomain( db=Depends(get_db), ): try: - return ApiReturnModel(data =domainService.get_default_domain(db, user.id)) + return ApiReturnModel(data =domainService.get_default_domain(db,user.id)) except Exception as e: raise APIException('platform:defaultdomain',request.url._url,f"Error occurred while get user({user.id}) defaultdomain:",e) @@ -498,7 +501,7 @@ async def set_defualtuserdomain( db=Depends(get_db), ): try: - domain = domainService.set_default_domain(db,user.id,domainid) + domain = domainCacheService.set_default_domain(db,user.id,domainid) return ApiReturnModel(data= domain) except Exception as e: raise APIException('platform:defaultdomain',request.url._url,f"Error occurred while update user({user.id}) defaultdomain:",e) diff --git a/backend/app/core/__init__.py b/backend/app/core/__init__.py index e69de29..21b6db6 100644 --- a/backend/app/core/__init__.py +++ b/backend/app/core/__init__.py @@ -0,0 +1 @@ +from app.core.cache import domainCacheService \ No newline at end of file diff --git a/backend/app/core/cache.py b/backend/app/core/cache.py new file mode 100644 index 0000000..da3f624 --- /dev/null +++ b/backend/app/core/cache.py @@ -0,0 +1,55 @@ +import time +from typing import Any +from sqlalchemy.orm import Session +from app.db.cruddb import domainService + +class MemoryCache: + def __init__(self, max_cache_size: int = 100, ttl: int = 60): + self.cache = {} + self.max_cache_size = max_cache_size + self.ttl = ttl + + def get(self, key: str) -> Any: + item = self.cache.get(key) + if item: + if time.time() - item['timestamp'] > self.ttl: + self.cache.pop(key) + return None + return item['value'] + return None + + def set(self, key: str, value: Any) -> None: + if len(self.cache) >= self.max_cache_size: + self.cache.pop(next(iter(self.cache))) + self.cache[key] = {'value': value, 'timestamp': time.time()} + + # def clear(self,key) -> None: + # self.cache.pop(key,None) + + def clear(self) -> None: + self.cache.clear() + + + +class domainCache: + + def __init__(self): + self.memoryCache = MemoryCache(max_cache_size=50, ttl=120) + + def set_default_domain(self, db: Session,userid: int,domainid:str): + domain = domainService.set_default_domain(db,userid,domainid) + if domain: + self.memoryCache.set(f"DOMAIN_{userid}",domain.url) + return domain + + def get_default_domainurl(self,db: Session, userid: int): + if not self.memoryCache.get(f"DOMAIN_{userid}"): + domain = domainService.get_default_domain(db,userid) + if domain: + self.memoryCache.set(f"DOMAIN_{userid}",domain.url) + return self.memoryCache.get(f"DOMAIN_{userid}") + + def clear_default_domainurl(self): + self.memoryCache.clear() + +domainCacheService =domainCache() \ No newline at end of file diff --git a/backend/app/db/cruddb/dbapp.py b/backend/app/db/cruddb/dbapp.py index f1b3721..228dfa8 100644 --- a/backend/app/db/cruddb/dbapp.py +++ b/backend/app/db/cruddb/dbapp.py @@ -47,7 +47,7 @@ class dbflow(crudbase): updateuserid = userid ) db.add(db_flow) - db_app = db.execute(select(models.App).filter(and_(models.App.domainurl == domainurl,models.App.appid == flow.appid))).scalars().first() + db_app = db.execute(select(models.App).where(and_(models.App.domainurl == domainurl,models.App.appid == flow.appid))).scalars().first() if not db_app: db_app = models.App( domainurl = domainurl, diff --git a/backend/app/tests/test_domain.py b/backend/app/tests/test_domain.py index 96d8992..f923f3d 100644 --- a/backend/app/tests/test_domain.py +++ b/backend/app/tests/test_domain.py @@ -57,8 +57,9 @@ def test_delete_domain(test_client, login_user): def test_set_defaultuserdomain(test_client, test_domain,login_user): response = test_client.put("/api/defaultdomain/"+str(test_domain.id), headers={"Authorization": "Bearer " + login_user}) - assert response.status_code == 200 data = response.json() + logging.error(data) + assert response.status_code == 200 assert "data" in data assert data["data"] is not None assert data["data"]["name"] == test_domain.name @@ -99,8 +100,9 @@ def test_edit_domain(test_client, test_domain, login_user): "is_active": True } response = test_client.put("/api/domain", json=update_domain,headers={"Authorization": "Bearer " + login_user}) - assert response.status_code == 200 data = response.json() + logging.error(data) + assert response.status_code == 200 assert "data" in data assert data["data"] is not None assert data["data"]["name"] == update_domain["name"] diff --git a/backend/app/tests/test_user_app.py b/backend/app/tests/test_user_app.py index 297ae7e..d416e73 100644 --- a/backend/app/tests/test_user_app.py +++ b/backend/app/tests/test_user_app.py @@ -37,8 +37,9 @@ def test_edit_flow(test_client,test_domain,test_app_id,login_user): "content": "" } response = test_client.put("/api/flow", json=test_flow,headers={"Authorization": "Bearer " + login_user}) - assert response.status_code == 200 data = response.json() + logging.error(data) + assert response.status_code == 200 assert "data" in data assert data["data"] is not None assert data["data"]["domainurl"] == test_domain.url