feat(F1): wire MinIO STL cache into render_still + render_turntable_to_file
Previously the cache_service was only used in the generate_stl_cache Celery task. All render paths (render_still, render_turntable_to_file, render_turntable_task) only checked for a local file and converted from scratch if missing. Changes: - render_blender.py: add _stl_from_cache_or_convert() helper that checks MinIO cache before falling back to local STEP→STL conversion. Wire into render_still() and render_turntable_to_file() (both STL conversion blocks). - domains/rendering/tasks.py: wire MinIO cache check into render_turntable_task() inline before convert_step_to_stl(). All errors are non-fatal (falls back to fresh conversion). Now a STEP file converted on one worker is available to all workers via MinIO, avoiding redundant cadquery conversions on re-renders. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -155,9 +155,20 @@ def render_turntable_task(
|
||||
scripts_dir = Path(os.environ.get("RENDER_SCRIPTS_DIR", "/render-scripts"))
|
||||
turntable_script = scripts_dir / "turntable_render.py"
|
||||
|
||||
# STL conversion
|
||||
# STL conversion — try MinIO cache first, then convert locally
|
||||
stl_path = step.parent / f"{step.stem}_{stl_quality}.stl"
|
||||
if not stl_path.exists() or stl_path.stat().st_size == 0:
|
||||
try:
|
||||
from app.domains.products.cache_service import compute_step_hash, check_stl_cache
|
||||
step_hash = compute_step_hash(str(step))
|
||||
cached = check_stl_cache(step_hash, stl_quality)
|
||||
if cached:
|
||||
stl_path.write_bytes(cached)
|
||||
logger.info("STL restored from MinIO cache: %s", stl_path.name)
|
||||
else:
|
||||
convert_step_to_stl(step, stl_path, stl_quality)
|
||||
except Exception as exc:
|
||||
logger.warning("MinIO cache check failed (non-fatal): %s — falling back to conversion", exc)
|
||||
convert_step_to_stl(step, stl_path, stl_quality)
|
||||
parts_dir = step.parent / f"{step.stem}_{stl_quality}_parts"
|
||||
if not (parts_dir / "manifest.json").exists():
|
||||
|
||||
@@ -17,6 +17,26 @@ logger = logging.getLogger(__name__)
|
||||
MIN_BLENDER_VERSION = (5, 0, 1)
|
||||
|
||||
|
||||
def _stl_from_cache_or_convert(step_path: Path, stl_path: Path, quality: str) -> None:
|
||||
"""Try MinIO cache first, then fall back to local STEP→STL conversion."""
|
||||
# MinIO cache check (non-fatal — cache miss just means we convert normally)
|
||||
try:
|
||||
from app.domains.products.cache_service import compute_step_hash, check_stl_cache
|
||||
step_hash = compute_step_hash(str(step_path))
|
||||
cached_bytes = check_stl_cache(step_hash, quality)
|
||||
if cached_bytes:
|
||||
stl_path.write_bytes(cached_bytes)
|
||||
logger.info("STL restored from MinIO cache: %s (%d KB)", stl_path.name, len(cached_bytes) // 1024)
|
||||
return
|
||||
except Exception as exc:
|
||||
logger.warning("MinIO cache check failed (non-fatal): %s", exc)
|
||||
|
||||
# Local conversion
|
||||
from app.services.step_processor import convert_step_to_stl
|
||||
logger.info("STL cache miss — converting: %s", step_path.name)
|
||||
convert_step_to_stl(step_path, stl_path, quality)
|
||||
|
||||
|
||||
def find_blender() -> str:
|
||||
"""Locate the Blender binary via $BLENDER_BIN or PATH."""
|
||||
env_bin = os.environ.get("BLENDER_BIN", "")
|
||||
@@ -210,10 +230,9 @@ def render_still(
|
||||
|
||||
t_stl = time.monotonic()
|
||||
if not stl_path.exists() or stl_path.stat().st_size == 0:
|
||||
logger.info("STL cache miss — converting: %s", step_path.name)
|
||||
convert_step_to_stl(step_path, stl_path, stl_quality)
|
||||
_stl_from_cache_or_convert(step_path, stl_path, stl_quality)
|
||||
else:
|
||||
logger.info("STL cache hit: %s (%d KB)", stl_path.name, stl_path.stat().st_size // 1024)
|
||||
logger.info("STL local hit: %s (%d KB)", stl_path.name, stl_path.stat().st_size // 1024)
|
||||
stl_size_bytes = stl_path.stat().st_size if stl_path.exists() else 0
|
||||
|
||||
if not (parts_dir / "manifest.json").exists():
|
||||
@@ -394,10 +413,9 @@ def render_turntable_to_file(
|
||||
|
||||
t_stl = time.monotonic()
|
||||
if not stl_path.exists() or stl_path.stat().st_size == 0:
|
||||
logger.info("STL cache miss — converting: %s", step_path.name)
|
||||
convert_step_to_stl(step_path, stl_path, stl_quality)
|
||||
_stl_from_cache_or_convert(step_path, stl_path, stl_quality)
|
||||
else:
|
||||
logger.info("STL cache hit: %s (%d KB)", stl_path.name, stl_path.stat().st_size // 1024)
|
||||
logger.info("STL local hit: %s (%d KB)", stl_path.name, stl_path.stat().st_size // 1024)
|
||||
stl_size_bytes = stl_path.stat().st_size if stl_path.exists() else 0
|
||||
|
||||
if not (parts_dir / "manifest.json").exists():
|
||||
|
||||
Reference in New Issue
Block a user