Hikity commited on
Commit
717e080
·
1 Parent(s): 2543a43

fix: warm EasyOCR at startup — cold-init on first currency request exceeded HF proxy timeout and 500'd after every container restart

Browse files
Files changed (2) hide show
  1. app/currency_detector.py +13 -8
  2. app/main.py +16 -0
app/currency_detector.py CHANGED
@@ -52,20 +52,25 @@ import numpy as np
52
  import torch
53
  import torch.nn as nn
54
 
 
 
55
  _easyocr_reader = None
 
56
 
57
 
58
  def _get_ocr_reader():
59
  """Lazy-loaded, process-wide EasyOCR reader (pure Python, no Tesseract
60
- binary dependency — heavy to init, so load once)."""
 
61
  global _easyocr_reader
62
- if _easyocr_reader is None:
63
- try:
64
- import easyocr
65
- _easyocr_reader = easyocr.Reader(["en"], gpu=torch.cuda.is_available(), verbose=False)
66
- except Exception as e:
67
- print(f"[CURRENCY] EasyOCR unavailable ({e}) — OCR-based checks will report not_applicable.")
68
- _easyocr_reader = False # sentinel: tried and failed, don't retry every call
 
69
  return _easyocr_reader or None
70
 
71
 
 
52
  import torch
53
  import torch.nn as nn
54
 
55
+ import threading
56
+
57
  _easyocr_reader = None
58
+ _easyocr_lock = threading.Lock()
59
 
60
 
61
  def _get_ocr_reader():
62
  """Lazy-loaded, process-wide EasyOCR reader (pure Python, no Tesseract
63
+ binary dependency — heavy to init, so load once). Lock-guarded because
64
+ startup warms it from a background thread while requests may arrive."""
65
  global _easyocr_reader
66
+ with _easyocr_lock:
67
+ if _easyocr_reader is None:
68
+ try:
69
+ import easyocr
70
+ _easyocr_reader = easyocr.Reader(["en"], gpu=torch.cuda.is_available(), verbose=False)
71
+ except Exception as e:
72
+ print(f"[CURRENCY] EasyOCR unavailable ({e}) — OCR-based checks will report not_applicable.")
73
+ _easyocr_reader = False # sentinel: tried and failed, don't retry every call
74
  return _easyocr_reader or None
75
 
76
 
app/main.py CHANGED
@@ -85,6 +85,22 @@ async def lifespan(app: FastAPI):
85
  currency_detector = CurrencyDetector(weights_dir=weights_dir, device=device)
86
  print(f" [OK] Currency detector ready (mode: {currency_detector.mode})")
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  print(f"\n{'='*60}")
89
  print(" KAWACH startup complete — 6 endpoints live")
90
  print(f"{'='*60}\n")
 
85
  currency_detector = CurrencyDetector(weights_dir=weights_dir, device=device)
86
  print(f" [OK] Currency detector ready (mode: {currency_detector.mode})")
87
 
88
+ # Warm EasyOCR in the background: its lazy first-call init takes long
89
+ # enough on the free-tier 2vCPU host that the first currency request
90
+ # after every container (re)start blew past the HF proxy timeout and
91
+ # 500'd (observed 2026-07-19 — failures rotated across images, warm
92
+ # container always fine). Boot stays fast; only OCR-dependent checks
93
+ # degrade gracefully until the thread finishes.
94
+ import threading
95
+ from app.currency_detector import _get_ocr_reader
96
+
97
+ def _warm_ocr():
98
+ print(" [P7] Warming EasyOCR reader (background)...")
99
+ _get_ocr_reader()
100
+ print(" [P7] EasyOCR reader warm")
101
+
102
+ threading.Thread(target=_warm_ocr, daemon=True).start()
103
+
104
  print(f"\n{'='*60}")
105
  print(" KAWACH startup complete — 6 endpoints live")
106
  print(f"{'='*60}\n")