modify song process flow
parent
7038faaf74
commit
4a06bfdde4
|
|
@ -92,18 +92,18 @@ async def get_session() -> AsyncGenerator[AsyncSession, None]:
|
||||||
pool = engine.pool
|
pool = engine.pool
|
||||||
|
|
||||||
# 커넥션 풀 상태 로깅 (디버깅용)
|
# 커넥션 풀 상태 로깅 (디버깅용)
|
||||||
logger.debug(
|
# logger.debug(
|
||||||
f"[get_session] ACQUIRE - pool_size: {pool.size()}, "
|
# f"[get_session] ACQUIRE - pool_size: {pool.size()}, "
|
||||||
f"in: {pool.checkedin()}, out: {pool.checkedout()}, "
|
# f"in: {pool.checkedin()}, out: {pool.checkedout()}, "
|
||||||
f"overflow: {pool.overflow()}"
|
# f"overflow: {pool.overflow()}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
async with AsyncSessionLocal() as session:
|
async with AsyncSessionLocal() as session:
|
||||||
acquire_time = time.perf_counter()
|
acquire_time = time.perf_counter()
|
||||||
logger.debug(
|
# logger.debug(
|
||||||
f"[get_session] Session acquired in "
|
# f"[get_session] Session acquired in "
|
||||||
f"{(acquire_time - start_time)*1000:.1f}ms"
|
# f"{(acquire_time - start_time)*1000:.1f}ms"
|
||||||
)
|
# )
|
||||||
try:
|
try:
|
||||||
yield session
|
yield session
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -115,10 +115,10 @@ async def get_session() -> AsyncGenerator[AsyncSession, None]:
|
||||||
raise e
|
raise e
|
||||||
finally:
|
finally:
|
||||||
total_time = time.perf_counter() - start_time
|
total_time = time.perf_counter() - start_time
|
||||||
logger.debug(
|
# logger.debug(
|
||||||
f"[get_session] RELEASE - duration: {total_time*1000:.1f}ms, "
|
# f"[get_session] RELEASE - duration: {total_time*1000:.1f}ms, "
|
||||||
f"pool_out: {pool.checkedout()}"
|
# f"pool_out: {pool.checkedout()}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
# 백그라운드 태스크용 세션 제너레이터
|
# 백그라운드 태스크용 세션 제너레이터
|
||||||
|
|
@ -126,18 +126,18 @@ async def get_background_session() -> AsyncGenerator[AsyncSession, None]:
|
||||||
start_time = time.perf_counter()
|
start_time = time.perf_counter()
|
||||||
pool = background_engine.pool
|
pool = background_engine.pool
|
||||||
|
|
||||||
logger.debug(
|
# logger.debug(
|
||||||
f"[get_background_session] ACQUIRE - pool_size: {pool.size()}, "
|
# f"[get_background_session] ACQUIRE - pool_size: {pool.size()}, "
|
||||||
f"in: {pool.checkedin()}, out: {pool.checkedout()}, "
|
# f"in: {pool.checkedin()}, out: {pool.checkedout()}, "
|
||||||
f"overflow: {pool.overflow()}"
|
# f"overflow: {pool.overflow()}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
async with BackgroundSessionLocal() as session:
|
async with BackgroundSessionLocal() as session:
|
||||||
acquire_time = time.perf_counter()
|
acquire_time = time.perf_counter()
|
||||||
logger.debug(
|
# logger.debug(
|
||||||
f"[get_background_session] Session acquired in "
|
# f"[get_background_session] Session acquired in "
|
||||||
f"{(acquire_time - start_time)*1000:.1f}ms"
|
# f"{(acquire_time - start_time)*1000:.1f}ms"
|
||||||
)
|
# )
|
||||||
try:
|
try:
|
||||||
yield session
|
yield session
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -150,11 +150,11 @@ async def get_background_session() -> AsyncGenerator[AsyncSession, None]:
|
||||||
raise e
|
raise e
|
||||||
finally:
|
finally:
|
||||||
total_time = time.perf_counter() - start_time
|
total_time = time.perf_counter() - start_time
|
||||||
logger.debug(
|
# logger.debug(
|
||||||
f"[get_background_session] RELEASE - "
|
# f"[get_background_session] RELEASE - "
|
||||||
f"duration: {total_time*1000:.1f}ms, "
|
# f"duration: {total_time*1000:.1f}ms, "
|
||||||
f"pool_out: {pool.checkedout()}"
|
# f"pool_out: {pool.checkedout()}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
# 앱 종료 시 엔진 리소스 정리 함수
|
# 앱 종료 시 엔진 리소스 정리 함수
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,7 @@ from app.dependencies.pagination import (
|
||||||
)
|
)
|
||||||
from app.home.models import Project
|
from app.home.models import Project
|
||||||
from app.lyric.models import Lyric
|
from app.lyric.models import Lyric
|
||||||
from app.song.models import Song, SongTimestamp
|
from app.song.models import Song
|
||||||
|
|
||||||
from app.song.schemas.song_schema import (
|
from app.song.schemas.song_schema import (
|
||||||
DownloadSongResponse,
|
DownloadSongResponse,
|
||||||
GenerateSongRequest,
|
GenerateSongRequest,
|
||||||
|
|
@ -344,14 +343,13 @@ async def get_song_status(
|
||||||
Azure Blob Storage에 업로드한 뒤 Song 테이블의 status를 completed로,
|
Azure Blob Storage에 업로드한 뒤 Song 테이블의 status를 completed로,
|
||||||
song_result_url을 Blob URL로 업데이트합니다.
|
song_result_url을 Blob URL로 업데이트합니다.
|
||||||
"""
|
"""
|
||||||
suno_task_id = song_id # 임시방편 / 외부 suno 노출 방지
|
logger.info(f"[get_song_status] START - song_id: {song_id}")
|
||||||
logger.info(f"[get_song_status] START - song_id: {suno_task_id}")
|
|
||||||
try:
|
try:
|
||||||
suno_service = SunoService()
|
suno_service = SunoService()
|
||||||
result = await suno_service.get_task_status(suno_task_id)
|
result = await suno_service.get_task_status(song_id)
|
||||||
logger.debug(f"[get_song_status] Suno API raw response - song_id: {suno_task_id}, result: {result}")
|
logger.debug(f"[get_song_status] Suno API raw response - song_id: {song_id}, result: {result}")
|
||||||
parsed_response = suno_service.parse_status_response(result)
|
parsed_response = suno_service.parse_status_response(result)
|
||||||
logger.info(f"[get_song_status] Suno API response - song_id: {suno_task_id}, status: {parsed_response.status}")
|
logger.info(f"[get_song_status] Suno API response - song_id: {song_id}, status: {parsed_response.status}")
|
||||||
|
|
||||||
# SUCCESS 상태인 경우 백그라운드에서 MP3 다운로드 및 Blob 업로드 진행
|
# SUCCESS 상태인 경우 백그라운드에서 MP3 다운로드 및 Blob 업로드 진행
|
||||||
if parsed_response.status == "SUCCESS" and result:
|
if parsed_response.status == "SUCCESS" and result:
|
||||||
|
|
@ -371,7 +369,7 @@ async def get_song_status(
|
||||||
# song_id로 Song 조회
|
# song_id로 Song 조회
|
||||||
song_result = await session.execute(
|
song_result = await session.execute(
|
||||||
select(Song)
|
select(Song)
|
||||||
.where(Song.suno_task_id == suno_task_id)
|
.where(Song.suno_task_id == song_id)
|
||||||
.order_by(Song.created_at.desc())
|
.order_by(Song.created_at.desc())
|
||||||
.limit(1)
|
.limit(1)
|
||||||
)
|
)
|
||||||
|
|
@ -390,51 +388,26 @@ async def get_song_status(
|
||||||
song.status = "uploading"
|
song.status = "uploading"
|
||||||
song.suno_audio_id = first_clip.get('id')
|
song.suno_audio_id = first_clip.get('id')
|
||||||
await session.commit()
|
await session.commit()
|
||||||
logger.info(f"[get_song_status] Song status changed to uploading - song_id: {suno_task_id}")
|
logger.info(f"[get_song_status] Song status changed to uploading - song_id: {song_id}")
|
||||||
|
|
||||||
# 백그라운드 태스크로 MP3 다운로드 및 Blob 업로드 실행
|
# 백그라운드 태스크로 MP3 다운로드 및 Blob 업로드 실행
|
||||||
background_tasks.add_task(
|
background_tasks.add_task(
|
||||||
download_and_upload_song_by_suno_task_id,
|
download_and_upload_song_by_suno_task_id,
|
||||||
suno_task_id=suno_task_id,
|
suno_task_id=song_id,
|
||||||
audio_url=audio_url,
|
audio_url=audio_url,
|
||||||
store_name=store_name,
|
store_name=store_name,
|
||||||
duration=clip_duration,
|
duration=clip_duration,
|
||||||
)
|
)
|
||||||
logger.info(f"[get_song_status] Background task scheduled - song_id: {suno_task_id}, store_name: {store_name}")
|
logger.info(f"[get_song_status] Background task scheduled - song_id: {song_id}, store_name: {store_name}")
|
||||||
|
|
||||||
suno_audio_id = first_clip.get('id')
|
|
||||||
word_data = await suno_service.get_lyric_timestamp(suno_task_id, suno_audio_id)
|
|
||||||
lyric_result = await session.execute(
|
|
||||||
select(Lyric)
|
|
||||||
.where(Lyric.task_id == song.task_id)
|
|
||||||
.order_by(Lyric.created_at.desc())
|
|
||||||
.limit(1)
|
|
||||||
)
|
|
||||||
lyric = lyric_result.scalar_one_or_none()
|
|
||||||
gt_lyric = lyric.lyric_result
|
|
||||||
lyric_line_list = gt_lyric.split("\n")
|
|
||||||
sentences = [lyric_line.strip(',. ') for lyric_line in lyric_line_list if lyric_line and lyric_line != "---"]
|
|
||||||
|
|
||||||
timestamped_lyrics = suno_service.align_lyrics(word_data, sentences)
|
|
||||||
# TODO : DB upload timestamped_lyrics
|
|
||||||
for order_idx, timestamped_lyric in enumerate(timestamped_lyrics):
|
|
||||||
song_timestamp = SongTimestamp(
|
|
||||||
suno_audio_id = suno_audio_id,
|
|
||||||
order_idx = order_idx,
|
|
||||||
lyric_line = timestamped_lyric["text"],
|
|
||||||
start_time = timestamped_lyric["start_sec"],
|
|
||||||
end_time = timestamped_lyric["end_sec"]
|
|
||||||
)
|
|
||||||
session.add(song_timestamp)
|
|
||||||
|
|
||||||
await session.commit()
|
|
||||||
|
|
||||||
elif song and song.status == "uploading":
|
elif song and song.status == "uploading":
|
||||||
logger.info(f"[get_song_status] SKIPPED - Song is already uploading, song_id: {suno_task_id}")
|
logger.info(f"[get_song_status] SKIPPED - Song is already uploading, song_id: {song_id}")
|
||||||
|
parsed_response.status == "uploading"
|
||||||
elif song and song.status == "completed":
|
elif song and song.status == "completed":
|
||||||
logger.info(f"[get_song_status] SKIPPED - Song already completed, song_id: {suno_task_id}")
|
logger.info(f"[get_song_status] SKIPPED - Song already completed, song_id: {song_id}")
|
||||||
|
parsed_response.status == "SUCCESS"
|
||||||
|
|
||||||
logger.info(f"[get_song_status] SUCCESS - song_id: {suno_task_id}")
|
logger.info(f"[get_song_status] song_id: {song_id}")
|
||||||
return parsed_response
|
return parsed_response
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue