| """ |
| ์ด ํ์ผ์ ์คํธ๋ฆผ๋ฆฟ ๋์๋ณด๋์ ์ต์ด ๋ก๋ฉ ์๊ฐ์ ์ ๊ฑฐํ๊ธฐ ์ํ ์ปค์คํ
์บ์ฑ ์คํฌ๋ฆฝํธ์
๋๋ค. |
| ๋ก์ปฌ ํ์ผ ์บ์๋ฅผ ์ฐ์ ์ ์ผ๋ก ๋ฐํํ๊ณ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๊ตฌ๊ธ ์ํธ์ ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐํํฉ๋๋ค. |
| """ |
| import os |
| import time |
| import pickle |
| import threading |
| import streamlit as st |
|
|
| BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
|
|
| def local_first_cache(cache_filename, ttl=3600): |
| """ |
| Stale-While-Revalidate (๋ก์ปฌ ์ฐ์ ์ฝ๊ธฐ) ํจํด์ ๊ตฌํํ ์ปค์คํ
์บ์ ๋ฐ์ฝ๋ ์ดํฐ. |
| - ๋ก์ปฌ์ pickle ์บ์๊ฐ ์์ผ๋ฉด 0.1์ด ๋ง์ ์ฆ์ ๋ฐํ (๋์๋ณด๋ ๋ก๋ฉ ๋๋ ์ด ์ ๊ฑฐ) |
| - ์บ์๊ฐ ttl๋ณด๋ค ์ค๋๋์์ผ๋ฉด ๊ธฐ์กด ์บ์๋ฅผ ๋ฐํํ ๋ค, ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ๊ตฌ๊ธ ์ํธ๋ฅผ ์กฐํํ์ฌ ์บ์๋ฅผ ์
๋ฐ์ดํธํจ |
| """ |
| def decorator(func): |
| def wrapper(*args, **kwargs): |
| cache_path = os.path.join(BASE_DIR, "scratch", cache_filename) |
| |
| |
| if os.path.exists(cache_path): |
| try: |
| with open(cache_path, "rb") as f: |
| data = pickle.load(f) |
| |
| |
| if time.time() - os.path.getmtime(cache_path) > ttl: |
| def _update_cache(): |
| try: |
| res = func(*args, **kwargs) |
| os.makedirs(os.path.dirname(cache_path), exist_ok=True) |
| with open(cache_path, "wb") as f: |
| pickle.dump(res, f) |
| except Exception as e: |
| print(f"[๊ฒฝ๊ณ ] ๋ฐฑ๊ทธ๋ผ์ด๋ ์บ์ ์
๋ฐ์ดํธ ์คํจ ({cache_filename}): {e}") |
| |
| threading.Thread(target=_update_cache, daemon=True).start() |
| |
| return data |
| except Exception as e: |
| print(f"[๊ฒฝ๊ณ ] ๋ก์ปฌ ์บ์ ์ฝ๊ธฐ ์คํจ ({cache_filename}), ๋๊ธฐ์์ผ๋ก ์ฌ์กฐํํฉ๋๋ค: {e}") |
| |
| |
| print(f"[์์] ์ต์ด ๋ฐ์ดํฐ ๋ก๋ ์ค... ({cache_filename})") |
| res = func(*args, **kwargs) |
| try: |
| os.makedirs(os.path.dirname(cache_path), exist_ok=True) |
| with open(cache_path, "wb") as f: |
| pickle.dump(res, f) |
| except Exception as e: |
| print(f"[๊ฒฝ๊ณ ] ๋ก์ปฌ ์บ์ ์ ์ฅ ์คํจ ({cache_filename}): {e}") |
| |
| return res |
| return wrapper |
| return decorator |
|
|