seawolf2357 commited on
Commit
5f5ce60
·
verified ·
1 Parent(s): 8bf9ee2

Update cache_db.py

Browse files
Files changed (1) hide show
  1. cache_db.py +177 -2
cache_db.py CHANGED
@@ -18,16 +18,191 @@ from datetime import datetime, timedelta
18
  from typing import List, Dict, Tuple, Optional, Generator
19
  from pathlib import Path
20
  import pytz
 
21
  logging.basicConfig(level=logging.INFO)
22
  logger = logging.getLogger(__name__)
23
- PERSISTENT_DIR = Path("/data") if os.path.exists("/data") else Path("./data")
24
- CACHE_DIR = PERSISTENT_DIR / "announcement_cache"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  DB_PATH = CACHE_DIR / "chroma_db"
26
  METADATA_FILE = CACHE_DIR / "sync_metadata.json"
27
  CONTENT_INDEX_FILE = CACHE_DIR / "content_index_status.json"
28
  PROFILE_DIR = CACHE_DIR / "user_profiles"
 
 
29
  CACHE_DIR.mkdir(parents=True, exist_ok=True)
30
  PROFILE_DIR.mkdir(parents=True, exist_ok=True)
 
 
 
 
 
31
  try:
32
  import chromadb
33
  from chromadb.config import Settings
 
18
  from typing import List, Dict, Tuple, Optional, Generator
19
  from pathlib import Path
20
  import pytz
21
+
22
  logging.basicConfig(level=logging.INFO)
23
  logger = logging.getLogger(__name__)
24
+
25
+ # ==================== 영구 스토리지 설정 (AETHER 패턴 적용) ====================
26
+
27
+ PERSISTENT_DIR = "/data"
28
+ LOCAL_FALLBACK_DIR = "./data"
29
+
30
+ # 전역 캐시 변수 (한 번만 결정)
31
+ _STORAGE_BASE_PATH = None
32
+
33
+ def _try_enable_persistent_storage_via_api() -> bool:
34
+ """HF API로 Persistent Storage 활성화 시도"""
35
+ hf_token = os.getenv("HF_TOKEN")
36
+ space_id = os.getenv("SPACE_ID")
37
+
38
+ if not hf_token:
39
+ logger.warning("⚠️ HF_TOKEN 환경변수 없음 - API 활성화 불가")
40
+ return False
41
+ if not space_id:
42
+ logger.warning("⚠️ SPACE_ID 환경변수 없음 - HF Spaces 환경이 아닌 것 같습니다")
43
+ return False
44
+
45
+ logger.info(f"🔄 Persistent Storage API 활성화 시도... Space ID: {space_id}")
46
+
47
+ try:
48
+ from huggingface_hub import HfApi, SpaceStorage
49
+ api = HfApi(token=hf_token)
50
+
51
+ try:
52
+ runtime = api.get_space_runtime(repo_id=space_id)
53
+ current_storage = getattr(runtime, 'storage', None)
54
+ if current_storage:
55
+ logger.info(f"✅ Persistent Storage 이미 활성화됨: {current_storage}")
56
+ return True
57
+ else:
58
+ logger.info("📦 Persistent Storage 비활성화 상태 - 활성화 시도...")
59
+ except Exception as e:
60
+ logger.warning(f"⚠️ Space 상태 확인 실패: {e}")
61
+
62
+ api.request_space_storage(repo_id=space_id, storage=SpaceStorage.SMALL)
63
+ logger.info("✅ Persistent Storage SMALL 활성화 요청 완료!")
64
+ logger.info("⏳ Space가 재시작됩니다. 잠시 후 /data 디렉토리가 생성됩니다.")
65
+ return True
66
+
67
+ except ImportError:
68
+ logger.warning("⚠️ huggingface_hub 라이브러리 없음")
69
+ return False
70
+ except Exception as e:
71
+ error_msg = str(e)
72
+ if "already" in error_msg.lower() or "exists" in error_msg.lower():
73
+ logger.info(f"✅ Persistent Storage 이미 활성화됨")
74
+ return True
75
+ elif "payment" in error_msg.lower() or "billing" in error_msg.lower():
76
+ logger.warning(f"⚠️ 결제 정보 필요: {error_msg}")
77
+ else:
78
+ logger.warning(f"⚠️ API 활성화 실패: {error_msg}")
79
+ return False
80
+
81
+ def _determine_storage_path() -> Path:
82
+ """영구 저장소 경로 결정 (AETHER 패턴)"""
83
+ global _STORAGE_BASE_PATH
84
+
85
+ # 이미 결정된 경우 캐시 반환
86
+ if _STORAGE_BASE_PATH is not None:
87
+ return _STORAGE_BASE_PATH
88
+
89
+ print("\n" + "=" * 60)
90
+ print("🔍 CoBIZ 캐시 스토리지 초기화 중...")
91
+ print("=" * 60)
92
+
93
+ # 1. /data 경로 확인 (HF Spaces Persistent Storage)
94
+ if os.path.exists(PERSISTENT_DIR):
95
+ try:
96
+ test_file = os.path.join(PERSISTENT_DIR, ".write_test")
97
+ with open(test_file, "w") as f:
98
+ f.write("test")
99
+ os.remove(test_file)
100
+
101
+ _STORAGE_BASE_PATH = Path(PERSISTENT_DIR)
102
+ logger.info(f"✅ HF Spaces 영구 스토리지 활성화: {PERSISTENT_DIR}")
103
+
104
+ # 기존 파일 확인
105
+ existing_files = [f for f in os.listdir(PERSISTENT_DIR)
106
+ if f.endswith('.db') or f.endswith('.json') or f == 'announcement_cache']
107
+ if existing_files:
108
+ logger.info(f"📁 기존 파일 발견: {existing_files}")
109
+ else:
110
+ logger.info("📁 기존 파일 없음 (새로운 스토리지)")
111
+
112
+ print("=" * 60 + "\n")
113
+ return _STORAGE_BASE_PATH
114
+
115
+ except Exception as e:
116
+ logger.warning(f"⚠️ /data 쓰기 테스트 실패: {e}")
117
+ else:
118
+ logger.warning(f"⚠️ {PERSISTENT_DIR} 디렉토리 없음")
119
+
120
+ # API로 활성화 시도
121
+ logger.info("\n🚀 API로 Persistent Storage 활성화 시도...")
122
+ if _try_enable_persistent_storage_via_api():
123
+ logger.info("💡 API 요청 완료. Space 재시작 후 /data 사용 가능")
124
+
125
+ # 2. 환경변수로 지정된 경로 확인
126
+ env_path = os.environ.get("PERSISTENT_DATA_DIR")
127
+ if env_path:
128
+ try:
129
+ os.makedirs(env_path, exist_ok=True)
130
+ test_file = os.path.join(env_path, ".write_test")
131
+ with open(test_file, "w") as f:
132
+ f.write("test")
133
+ os.remove(test_file)
134
+
135
+ _STORAGE_BASE_PATH = Path(env_path)
136
+ logger.info(f"✅ 환경변수 스토리지 사용: {env_path}")
137
+ print("=" * 60 + "\n")
138
+ return _STORAGE_BASE_PATH
139
+ except Exception as e:
140
+ logger.warning(f"⚠️ PERSISTENT_DATA_DIR 쓰기 불가: {e}")
141
+
142
+ # 3. 로컬 폴백 (비영구)
143
+ os.makedirs(LOCAL_FALLBACK_DIR, exist_ok=True)
144
+ _STORAGE_BASE_PATH = Path(LOCAL_FALLBACK_DIR)
145
+
146
+ logger.warning(f"\n🟡 현재 로컬 스토리지 사용: {LOCAL_FALLBACK_DIR}")
147
+ logger.warning(" ⚠️ 재시작 시 모든 데이터가 손실됩니다!")
148
+ logger.warning(" 💡 HF Space Settings → Persistent Storage → Enable 필요!")
149
+ print("=" * 60 + "\n")
150
+
151
+ return _STORAGE_BASE_PATH
152
+
153
+ def get_storage_info() -> dict:
154
+ """스토리지 상태 정보 반환"""
155
+ base_path = _determine_storage_path()
156
+ cache_dir = base_path / "announcement_cache"
157
+
158
+ info = {
159
+ "base_path": str(base_path),
160
+ "is_persistent": str(base_path) == PERSISTENT_DIR,
161
+ "cache_dir": str(cache_dir),
162
+ "cache_exists": cache_dir.exists(),
163
+ "files": []
164
+ }
165
+
166
+ if cache_dir.exists():
167
+ info["files"] = [f for f in os.listdir(cache_dir) if not f.startswith('.')]
168
+
169
+ return info
170
+
171
+ def verify_storage_persistence():
172
+ """스토리지 영속성 검증 (디버깅용)"""
173
+ base_path = _determine_storage_path()
174
+ cache_dir = base_path / "announcement_cache"
175
+
176
+ logger.info(f"\n🔍 스토리지 영속성 검증:")
177
+ logger.info(f" 기본 경로: {base_path}")
178
+ logger.info(f" 영구 저장: {'✅ 예' if str(base_path) == PERSISTENT_DIR else '❌ 아니오'}")
179
+ logger.info(f" 캐시 디렉토리: {cache_dir}")
180
+ logger.info(f" 캐시 존재: {cache_dir.exists()}")
181
+
182
+ if cache_dir.exists():
183
+ files = list(cache_dir.iterdir())
184
+ logger.info(f" 파일 수: {len(files)}")
185
+ for f in files[:5]: # 최대 5개만 표시
186
+ logger.info(f" - {f.name}")
187
+
188
+ # 초기화 실행
189
+ PERSISTENT_DIR_PATH = _determine_storage_path()
190
+ verify_storage_persistence()
191
+ # 경로 설정 (초기화된 PERSISTENT_DIR_PATH 사용)
192
+ CACHE_DIR = PERSISTENT_DIR_PATH / "announcement_cache"
193
  DB_PATH = CACHE_DIR / "chroma_db"
194
  METADATA_FILE = CACHE_DIR / "sync_metadata.json"
195
  CONTENT_INDEX_FILE = CACHE_DIR / "content_index_status.json"
196
  PROFILE_DIR = CACHE_DIR / "user_profiles"
197
+
198
+ # 디렉토리 생성
199
  CACHE_DIR.mkdir(parents=True, exist_ok=True)
200
  PROFILE_DIR.mkdir(parents=True, exist_ok=True)
201
+
202
+ # 저장 경로 로깅
203
+ logger.info(f"Cache directory: {CACHE_DIR}")
204
+ logger.info(f"Profile directory: {PROFILE_DIR}")
205
+ logger.info(f"Persistent storage: {'✅ YES' if str(PERSISTENT_DIR_PATH) == PERSISTENT_DIR else '❌ NO (local only)'}")
206
  try:
207
  import chromadb
208
  from chromadb.config import Settings