luh1124 commited on
Commit
ffb265b
·
1 Parent(s): 2396b9c

fix(space): avoid deleting Gradio cache and tmp_gradio paths still in UI

Browse files
Files changed (1) hide show
  1. app.py +30 -5
app.py CHANGED
@@ -141,10 +141,25 @@ MAX_SEED = np.iinfo(np.int32).max
141
  # Session helpers
142
  # ---------------------------------------------------------------------------
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  def ensure_session_dir(req: Optional[gr.Request]) -> Path:
145
  session_id = getattr(req, "session_hash", None) or "shared"
146
  d = CACHE_DIR / str(session_id)
147
  d.mkdir(parents=True, exist_ok=True)
 
148
  return d
149
 
150
 
@@ -159,8 +174,10 @@ def clear_session_dir(req: Optional[gr.Request]) -> str:
159
 
160
 
161
  def end_session(req: gr.Request):
162
- d = ensure_session_dir(req)
 
163
  shutil.rmtree(d, ignore_errors=True)
 
164
 
165
 
166
  def _session_dir_latest_mtime(path: Path) -> float:
@@ -183,12 +200,14 @@ def _session_dir_latest_mtime(path: Path) -> float:
183
 
184
 
185
  def prune_tmp_gradio_sessions(max_age_s: int) -> int:
186
- """Delete CACHE_DIR/<session> trees with no nested file activity for max_age_s. Returns removed count."""
187
 
188
  if max_age_s <= 0 or not CACHE_DIR.is_dir():
189
  return 0
190
  now = time.time()
191
  removed = 0
 
 
192
  try:
193
  entries = list(CACHE_DIR.iterdir())
194
  except OSError:
@@ -196,10 +215,15 @@ def prune_tmp_gradio_sessions(max_age_s: int) -> int:
196
  for p in entries:
197
  if not p.is_dir():
198
  continue
 
199
  try:
200
- if now - _session_dir_latest_mtime(p) < max_age_s:
 
 
 
201
  continue
202
  shutil.rmtree(p, ignore_errors=True)
 
203
  removed += 1
204
  except OSError:
205
  continue
@@ -221,7 +245,7 @@ def start_tmp_gradio_pruner() -> None:
221
  if _tmp_pruner_started:
222
  return
223
  _tmp_pruner_started = True
224
- max_age = int(os.environ.get("NEAR_TMP_GRADIO_MAX_AGE_S", str(6 * 3600)))
225
 
226
  def _loop() -> None:
227
  while True:
@@ -848,7 +872,8 @@ def build_app() -> gr.Blocks:
848
  ),
849
  title="NeAR",
850
  css=CUSTOM_CSS,
851
- delete_cache=(600, 600),
 
852
  fill_width=True,
853
  ) as demo:
854
  asset_state = gr.State({})
 
141
  # Session helpers
142
  # ---------------------------------------------------------------------------
143
 
144
+ _SESSION_LAST_TOUCH: Dict[str, float] = {}
145
+ _SESSION_TOUCH_LOCK = threading.Lock()
146
+
147
+
148
+ def _session_touch(session_id: str) -> None:
149
+ with _SESSION_TOUCH_LOCK:
150
+ _SESSION_LAST_TOUCH[session_id] = time.time()
151
+
152
+
153
+ def _session_forget(session_id: str) -> None:
154
+ with _SESSION_TOUCH_LOCK:
155
+ _SESSION_LAST_TOUCH.pop(session_id, None)
156
+
157
+
158
  def ensure_session_dir(req: Optional[gr.Request]) -> Path:
159
  session_id = getattr(req, "session_hash", None) or "shared"
160
  d = CACHE_DIR / str(session_id)
161
  d.mkdir(parents=True, exist_ok=True)
162
+ _session_touch(session_id)
163
  return d
164
 
165
 
 
174
 
175
 
176
  def end_session(req: gr.Request):
177
+ session_id = getattr(req, "session_hash", None) or "shared"
178
+ d = CACHE_DIR / str(session_id)
179
  shutil.rmtree(d, ignore_errors=True)
180
+ _session_forget(session_id)
181
 
182
 
183
  def _session_dir_latest_mtime(path: Path) -> float:
 
200
 
201
 
202
  def prune_tmp_gradio_sessions(max_age_s: int) -> int:
203
+ """Delete CACHE_DIR/<session> when both API idle and on-disk files are older than max_age_s."""
204
 
205
  if max_age_s <= 0 or not CACHE_DIR.is_dir():
206
  return 0
207
  now = time.time()
208
  removed = 0
209
+ with _SESSION_TOUCH_LOCK:
210
+ touch_snap = dict(_SESSION_LAST_TOUCH)
211
  try:
212
  entries = list(CACHE_DIR.iterdir())
213
  except OSError:
 
215
  for p in entries:
216
  if not p.is_dir():
217
  continue
218
+ sid = p.name
219
  try:
220
+ last_api = touch_snap.get(sid)
221
+ latest_file = _session_dir_latest_mtime(p)
222
+ last_seen = max(last_api or 0.0, latest_file)
223
+ if now - last_seen < max_age_s:
224
  continue
225
  shutil.rmtree(p, ignore_errors=True)
226
+ _session_forget(sid)
227
  removed += 1
228
  except OSError:
229
  continue
 
245
  if _tmp_pruner_started:
246
  return
247
  _tmp_pruner_started = True
248
+ max_age = int(os.environ.get("NEAR_TMP_GRADIO_MAX_AGE_S", str(48 * 3600)))
249
 
250
  def _loop() -> None:
251
  while True:
 
872
  ),
873
  title="NeAR",
874
  css=CUSTOM_CSS,
875
+ # (600, 600) deletes Gradio /tmp/gradio uploads in ~10m while the UI may still reference paths.
876
+ delete_cache=None,
877
  fill_width=True,
878
  ) as demo:
879
  asset_state = gr.State({})