From 912cd18e48ca543cfda67e994d24c9674283ecd4 Mon Sep 17 00:00:00 2001 From: gahusb Date: Tue, 19 May 2026 02:18:12 +0900 Subject: [PATCH] =?UTF-8?q?feat(insta-lab):=20cutover=20to=20Redis=20push,?= =?UTF-8?q?=20Playwright=20=EB=A0=8C=EB=8D=94=20=ED=98=B8=EC=B6=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20(SP-4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _bg_create_slate, _bg_render의 await card_renderer.render_slate(...) 호출을 Redis RPUSH queue:insta-render 로 전환. NAS는 task_id 발급 + 큐 푸시 + 30~70% 진행률 보고만. Windows insta-render 워커가 BLPOP → 렌더 → webhook으로 succeeded 보고 시 NAS가 update_slate_status('rendered') 트리거. Plan-B-Insta Phase 3 (cutover). Co-Authored-By: Claude Opus 4.7 (1M context) --- insta-lab/app/internal_router.py | 6 ++++++ insta-lab/app/main.py | 33 +++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/insta-lab/app/internal_router.py b/insta-lab/app/internal_router.py index 38be8e5..f4e00ae 100644 --- a/insta-lab/app/internal_router.py +++ b/insta-lab/app/internal_router.py @@ -56,6 +56,12 @@ def insta_update(payload: UpdatePayload): result_id=result_id, error=payload.error, ) + # succeeded 시 slate_status도 'rendered'로 갱신 (cutover 후 NAS가 처리) + if payload.status == "succeeded" and result_id is not None: + try: + db.update_slate_status(result_id, "rendered") + except Exception: + logger.exception("update_slate_status %s 실패 (무시)", result_id) logger.info( "internal/insta/update task=%s status=%s progress=%d", payload.task_id, payload.status, payload.progress, diff --git a/insta-lab/app/main.py b/insta-lab/app/main.py index 31539e2..93b56ac 100644 --- a/insta-lab/app/main.py +++ b/insta-lab/app/main.py @@ -161,12 +161,20 @@ async def _bg_create_slate(task_id: str, keyword: str, category: str, keyword_id try: db.update_task(task_id, "processing", 30, "카피 생성 중") sid = card_writer.write_slate(keyword=keyword, category=category) - db.update_task(task_id, "processing", 70, "카드 렌더 중") - await card_renderer.render_slate(sid, template=f"{INSTA_DEFAULT_THEME}/card.html.j2") - db.update_slate_status(sid, "rendered") if keyword_id: db.mark_keyword_used(keyword_id) - db.update_task(task_id, "succeeded", 100, "완료", result_id=sid) + # Redis 큐에 push — Windows insta-render worker가 BLPOP 후 렌더 + from datetime import datetime, timezone, timedelta + kst = timezone(timedelta(hours=9)) + payload = { + "task_id": task_id, + "kind": "insta", + "params": {"slate_id": sid, "theme": INSTA_DEFAULT_THEME}, + "submitted_at": datetime.now(kst).isoformat(), + } + await redis_client.rpush("queue:insta-render", json.dumps(payload)) + # 사용자는 GET /api/insta/tasks/{task_id}로 폴링 — worker가 webhook으로 status update + db.update_task(task_id, "processing", 70, "Redis 큐 푸시 → Windows worker 대기 중", result_id=sid) except Exception as e: logger.exception("create slate failed") db.update_task(task_id, "failed", 0, "", error=str(e)) @@ -200,13 +208,20 @@ def get_slate(slate_id: int): async def _bg_render(task_id: str, slate_id: int): + """Redis 큐에 push. 실 렌더는 Windows insta-render worker.""" try: - db.update_task(task_id, "processing", 30, "재렌더 중") - await card_renderer.render_slate(slate_id, template=f"{INSTA_DEFAULT_THEME}/card.html.j2") - db.update_slate_status(slate_id, "rendered") - db.update_task(task_id, "succeeded", 100, "완료", result_id=slate_id) + from datetime import datetime, timezone, timedelta + kst = timezone(timedelta(hours=9)) + payload = { + "task_id": task_id, + "kind": "insta", + "params": {"slate_id": slate_id, "theme": INSTA_DEFAULT_THEME}, + "submitted_at": datetime.now(kst).isoformat(), + } + await redis_client.rpush("queue:insta-render", json.dumps(payload)) + db.update_task(task_id, "processing", 30, "Redis 큐 푸시 → Windows worker 대기 중") except Exception as e: - logger.exception("render failed") + logger.exception("queue push failed") db.update_task(task_id, "failed", 0, "", error=str(e))