Refine seller store implementation
This commit is contained in:
@@ -26,6 +26,7 @@ from services.storage import get_storage
|
||||
from services.suite_service import append_generated_asset
|
||||
from services.tasks import TaskImage
|
||||
from services.watermark import apply_watermark
|
||||
from services.video_renderer import VideoRenderCancelled, render_slideshow
|
||||
|
||||
log = logging.getLogger("background.worker")
|
||||
|
||||
@@ -113,11 +114,52 @@ async def _process_watermark_item(claim: ClaimedItem) -> None:
|
||||
await mark_item_failed(claim.item_id, str(exc))
|
||||
|
||||
|
||||
async def _process_slideshow_video_item(claim: ClaimedItem) -> None:
|
||||
"""一个视频任务只有一个子项;输入 URL 在提交时冻结,避免后续选择状态影响成片。"""
|
||||
payload = claim.request_payload
|
||||
sources = list(payload.get("sources") or [])
|
||||
source_urls = [str(source.get("url") or "") for source in sources]
|
||||
if not 2 <= len(source_urls) <= 5 or any(not url for url in source_urls):
|
||||
await mark_item_failed(claim.item_id, "视频任务缺少 2–5 张可用图片")
|
||||
return
|
||||
try:
|
||||
async def should_cancel() -> bool:
|
||||
return not await job_can_write(claim.job_id)
|
||||
|
||||
rendered = await render_slideshow(source_urls, should_cancel=should_cancel)
|
||||
if not await job_can_write(claim.job_id):
|
||||
await mark_item_cancelled(claim.item_id)
|
||||
return
|
||||
key = f"products/{claim.product_id}/videos/{claim.job_id}/result.mp4"
|
||||
result_url = await get_storage().save_bytes(rendered.data, key, "video/mp4")
|
||||
async with get_session_factory()() as db:
|
||||
from models import BackgroundJobItem
|
||||
item = await db.get(BackgroundJobItem, uuid.UUID(claim.item_id))
|
||||
if item is not None:
|
||||
item.payload = {
|
||||
**dict(item.payload),
|
||||
"duration_seconds": rendered.duration_seconds,
|
||||
"width": rendered.width,
|
||||
"height": rendered.height,
|
||||
"file_size_bytes": len(rendered.data),
|
||||
}
|
||||
await db.commit()
|
||||
await mark_item_done(claim.item_id, result_url=result_url, source_url=None, watermark_config=None, generated_asset_id=None)
|
||||
except VideoRenderCancelled:
|
||||
await mark_item_cancelled(claim.item_id)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
log.exception("后台轮播视频任务 %s/%s 执行失败", claim.job_id, claim.item_id)
|
||||
await mark_item_failed(claim.item_id, str(exc))
|
||||
|
||||
|
||||
async def process_item(claim: ClaimedItem) -> None:
|
||||
"""推进一次子任务。外部模型未完成时只写 provider id 并退出,让出 Worker。"""
|
||||
if claim.job_kind == "watermark_batch":
|
||||
await _process_watermark_item(claim)
|
||||
return
|
||||
if claim.job_kind == "slideshow_video":
|
||||
await _process_slideshow_video_item(claim)
|
||||
return
|
||||
if claim.job_kind not in {"image_suite", "image_edit"}:
|
||||
await mark_item_failed(claim.item_id, f"Worker 暂不支持任务类型: {claim.job_kind}")
|
||||
return
|
||||
@@ -201,7 +243,7 @@ async def run_worker(*, once: bool = False, idle_seconds: float = 0.75) -> None:
|
||||
log.warning("恢复了 %d 个过期后台任务租约", recovered)
|
||||
log.info("后台 Worker 已启动:%s", owner)
|
||||
while True:
|
||||
claim = await claim_next_item(owner)
|
||||
claim = await claim_next_item(owner, lease_seconds=get_settings().background_job_lease_seconds)
|
||||
if claim is None:
|
||||
if once:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user