refactor(music-lab): batch_generator _generate_one_track → Redis push (SP-6)

기존 직접 run_suno_generation 호출 + asyncio.to_thread를
Redis push (queue:music-render, job_type=suno_generation) +
task 상태 polling 패턴으로 변경. 결과는 task_id로 music_library 조회.
Plan-B-Music Phase 3 (cutover 3/4).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 05:19:41 +09:00
parent 532b794c11
commit b1e28aa725

View File

@@ -102,8 +102,10 @@ async def run_batch(batch_id: int) -> None:
async def _generate_one_track(*, title: str, genre: str, duration_sec: int, async def _generate_one_track(*, title: str, genre: str, duration_sec: int,
params: dict) -> int | None: params: dict) -> int | None:
"""기존 Suno generate 호출 + 완료까지 polling. 성공 시 새 track id, 실패 시 None.""" """Redis 큐에 push + task 상태 polling. 성공 시 새 track id, 실패 시 None."""
from .suno_provider import run_suno_generation import json
from datetime import datetime, timezone, timedelta
from .main import redis_client # 같은 컨테이너 — 동일 redis 클라이언트 공유
task_id = str(uuid.uuid4()) task_id = str(uuid.uuid4())
suno_params = { suno_params = {
@@ -116,11 +118,23 @@ async def _generate_one_track(*, title: str, genre: str, duration_sec: int,
"key": params["key"], "key": params["key"],
"scale": params["scale"], "scale": params["scale"],
"prompt": params.get("prompt_modifier", ""), "prompt": params.get("prompt_modifier", ""),
"provider": "suno",
"model": "V4",
"instrumental": False,
"lyrics": "",
} }
db.create_task(task_id, suno_params, provider="suno") db.create_task(task_id, suno_params, provider="suno")
# Suno background task — 우리가 await로 기다림 (BackgroundTasks 미사용) # Redis push (Windows music-render가 BLPOP 처리)
asyncio.create_task(asyncio.to_thread(run_suno_generation, task_id, suno_params)) kst = timezone(timedelta(hours=9))
payload = {
"task_id": task_id,
"kind": "music",
"job_type": "suno_generation",
"params": suno_params,
"submitted_at": datetime.now(kst).isoformat(),
}
await redis_client.rpush("queue:music-render", json.dumps(payload))
waited = 0 waited = 0
while waited < TRACK_GEN_TIMEOUT_S: while waited < TRACK_GEN_TIMEOUT_S:
@@ -131,14 +145,7 @@ async def _generate_one_track(*, title: str, genre: str, duration_sec: int,
continue continue
status = task.get("status") status = task.get("status")
if status == "succeeded": if status == "succeeded":
# task["track"] 또는 task["result"]["track"] 형태 시도, 없으면 task_id로 조회 # Windows webhook이 add_track 했으므로 task_id로 검색
tr = task.get("track")
if tr and isinstance(tr, dict):
return tr.get("id")
result = task.get("result", {}) or {}
if isinstance(result, dict) and isinstance(result.get("track"), dict):
return result["track"].get("id")
# Fallback: music_library에서 task_id로 검색
track = db.get_track_by_task_id(task_id) track = db.get_track_by_task_id(task_id)
if track: if track:
return track.get("id") return track.get("id")