refactor(transcode): thread fs ops + atomic cache publish
- run blocking Path.exists/read_text off the event loop via anyio.to_thread - publish HLS renditions by building into a temp dir then atomic rename, so a reader never sees a playlist referencing half-written segments - per-writer temp name for opus so two concurrent jobs can't interleave - drop a track's cached renditions on delete so they don't dangle Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import re
|
||||
import uuid
|
||||
from typing import Annotated
|
||||
|
||||
import anyio
|
||||
from fastapi import APIRouter, Header, Query, Response
|
||||
from fastapi.responses import FileResponse, StreamingResponse
|
||||
|
||||
@@ -78,7 +79,7 @@ async def stream_hls_playlist(
|
||||
await enqueue_transcode_quiet(track_id, hls=True)
|
||||
raise NotFoundError("HLS rendition is being prepared; retry shortly.")
|
||||
|
||||
body = path.read_text()
|
||||
body = await anyio.to_thread.run_sync(path.read_text)
|
||||
if token:
|
||||
body = _SEGMENT_LINE_RE.sub(rf"\1?token={token}", body)
|
||||
return Response(body, media_type=_HLS_PLAYLIST_TYPE)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import uuid
|
||||
from typing import Annotated
|
||||
|
||||
import anyio
|
||||
from fastapi import APIRouter, Query, Response
|
||||
from fastapi.responses import StreamingResponse
|
||||
|
||||
@@ -33,7 +34,8 @@ from app.api.schemas.track import (
|
||||
TrackUpdate,
|
||||
)
|
||||
from app.api.schemas.transcode import OptimizeEnqueuedOut
|
||||
from app.application.transcode_service import bitrate_for_quality
|
||||
from app.application.transcode_service import bitrate_for_quality, remove_track_cache
|
||||
from app.core.config import get_settings
|
||||
from app.domain.entities.album import Album
|
||||
from app.domain.entities.track import Artist, Track
|
||||
from app.domain.errors import NotFoundError, ValidationError
|
||||
@@ -219,6 +221,10 @@ async def delete_track(
|
||||
await track_repo.delete(track_id)
|
||||
if track.storage_uri is not None:
|
||||
await storage.delete(track.storage_uri)
|
||||
# Drop any cached transcode renditions (Opus + HLS) so they don't dangle.
|
||||
await anyio.to_thread.run_sync(
|
||||
remove_track_cache, get_settings().transcode_cache_path, track_id
|
||||
)
|
||||
return Response(status_code=204)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user