|
@@ -21,11 +21,13 @@ from agents.find_agent.demand_run import (
|
|
|
)
|
|
)
|
|
|
from supply_infra.config import get_infra_settings
|
|
from supply_infra.config import get_infra_settings
|
|
|
from supply_infra.db.repositories.demand_grade_repo import DemandGradeRepository
|
|
from supply_infra.db.repositories.demand_grade_repo import DemandGradeRepository
|
|
|
|
|
+from supply_infra.db.repositories.video_discovery_repo import VideoDiscoveryRepository
|
|
|
from supply_infra.db.session import get_session
|
|
from supply_infra.db.session import get_session
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
_DEFAULT_WORKERS = 1
|
|
_DEFAULT_WORKERS = 1
|
|
|
|
|
+_DAILY_PASSED_VIDEO_LIMIT = 200
|
|
|
|
|
|
|
|
|
|
|
|
|
def _resolve_biz_dt(biz_dt: str | None) -> str:
|
|
def _resolve_biz_dt(biz_dt: str | None) -> str:
|
|
@@ -96,6 +98,11 @@ def process_single_discover(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def _count_passed_videos(biz_dt: str) -> int:
|
|
|
|
|
+ with get_session() as session:
|
|
|
|
|
+ return VideoDiscoveryRepository(session).count_passed_videos(biz_dt)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def discover_videos_from_demands(
|
|
def discover_videos_from_demands(
|
|
|
biz_dt: str | None = None,
|
|
biz_dt: str | None = None,
|
|
|
*,
|
|
*,
|
|
@@ -144,8 +151,10 @@ def discover_videos_from_demands(
|
|
|
if limit is not None and limit >= 0:
|
|
if limit is not None and limit >= 0:
|
|
|
contexts = contexts[: int(limit)]
|
|
contexts = contexts[: int(limit)]
|
|
|
|
|
|
|
|
|
|
+ passed_videos = _count_passed_videos(resolved_biz_dt)
|
|
|
|
|
+
|
|
|
logger.info(
|
|
logger.info(
|
|
|
- "discover_videos_from_demands start: biz_dt=%s batch_run_id=%s workers=%s top_limit=%s offset=%s pending=%s skipped=%s",
|
|
|
|
|
|
|
+ "discover_videos_from_demands start: biz_dt=%s batch_run_id=%s workers=%s top_limit=%s offset=%s pending=%s skipped=%s passed_videos=%s passed_video_limit=%s",
|
|
|
resolved_biz_dt,
|
|
resolved_biz_dt,
|
|
|
batch_run_id,
|
|
batch_run_id,
|
|
|
workers,
|
|
workers,
|
|
@@ -153,6 +162,8 @@ def discover_videos_from_demands(
|
|
|
offset,
|
|
offset,
|
|
|
len(contexts),
|
|
len(contexts),
|
|
|
preload_stats.get("skipped_already_done", 0),
|
|
preload_stats.get("skipped_already_done", 0),
|
|
|
|
|
+ passed_videos,
|
|
|
|
|
+ _DAILY_PASSED_VIDEO_LIMIT,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
result: dict[str, Any] = {
|
|
result: dict[str, Any] = {
|
|
@@ -170,9 +181,13 @@ def discover_videos_from_demands(
|
|
|
"skipped": 0,
|
|
"skipped": 0,
|
|
|
"failed": 0,
|
|
"failed": 0,
|
|
|
"errors": [],
|
|
"errors": [],
|
|
|
|
|
+ "passed_videos": passed_videos,
|
|
|
|
|
+ "passed_video_limit": _DAILY_PASSED_VIDEO_LIMIT,
|
|
|
|
|
+ "stopped_by_passed_video_limit": passed_videos
|
|
|
|
|
+ >= _DAILY_PASSED_VIDEO_LIMIT,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if not contexts:
|
|
|
|
|
|
|
+ if not contexts or passed_videos >= _DAILY_PASSED_VIDEO_LIMIT:
|
|
|
finished_at = datetime.now()
|
|
finished_at = datetime.now()
|
|
|
result["finished_at"] = finished_at.isoformat()
|
|
result["finished_at"] = finished_at.isoformat()
|
|
|
result["duration_seconds"] = round((finished_at - started_at).total_seconds(), 2)
|
|
result["duration_seconds"] = round((finished_at - started_at).total_seconds(), 2)
|
|
@@ -183,41 +198,61 @@ def discover_videos_from_demands(
|
|
|
result["workers"] = worker_count
|
|
result["workers"] = worker_count
|
|
|
|
|
|
|
|
with ThreadPoolExecutor(max_workers=worker_count) as executor:
|
|
with ThreadPoolExecutor(max_workers=worker_count) as executor:
|
|
|
- futures = [
|
|
|
|
|
- executor.submit(process_single_discover, ctx, force=force)
|
|
|
|
|
- for ctx in contexts
|
|
|
|
|
- ]
|
|
|
|
|
- for future in as_completed(futures):
|
|
|
|
|
- try:
|
|
|
|
|
- item_result = future.result()
|
|
|
|
|
- except Exception as exc:
|
|
|
|
|
- logger.exception(
|
|
|
|
|
- "discover videos worker 出现未捕获错误: biz_dt=%s",
|
|
|
|
|
- resolved_biz_dt,
|
|
|
|
|
- )
|
|
|
|
|
- result["failed"] += 1
|
|
|
|
|
- result["processed"] += 1
|
|
|
|
|
- result["errors"].append({"error": str(exc)})
|
|
|
|
|
- continue
|
|
|
|
|
-
|
|
|
|
|
- result["processed"] += 1
|
|
|
|
|
- if item_result.get("skipped"):
|
|
|
|
|
- result["skipped"] += 1
|
|
|
|
|
- continue
|
|
|
|
|
- if item_result.get("success"):
|
|
|
|
|
- result["succeeded"] += 1
|
|
|
|
|
- continue
|
|
|
|
|
-
|
|
|
|
|
- result["failed"] += 1
|
|
|
|
|
- result["errors"].append(
|
|
|
|
|
- {
|
|
|
|
|
- "demand_grade_id": item_result.get("demand_grade_id"),
|
|
|
|
|
- "demand_name": item_result.get("demand_name"),
|
|
|
|
|
- "video_count": item_result.get("video_count"),
|
|
|
|
|
- "run_id": item_result.get("run_id"),
|
|
|
|
|
- "error": item_result.get("error"),
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ next_context = 0
|
|
|
|
|
+ while next_context < len(contexts):
|
|
|
|
|
+ remaining_slots = _DAILY_PASSED_VIDEO_LIMIT - passed_videos
|
|
|
|
|
+ if remaining_slots <= 0:
|
|
|
|
|
+ result["stopped_by_passed_video_limit"] = True
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+ batch_size = min(
|
|
|
|
|
+ worker_count,
|
|
|
|
|
+ remaining_slots,
|
|
|
|
|
+ len(contexts) - next_context,
|
|
|
)
|
|
)
|
|
|
|
|
+ batch = contexts[next_context : next_context + batch_size]
|
|
|
|
|
+ next_context += batch_size
|
|
|
|
|
+ futures = [
|
|
|
|
|
+ executor.submit(process_single_discover, ctx, force=force)
|
|
|
|
|
+ for ctx in batch
|
|
|
|
|
+ ]
|
|
|
|
|
+ for future in as_completed(futures):
|
|
|
|
|
+ try:
|
|
|
|
|
+ item_result = future.result()
|
|
|
|
|
+ except Exception as exc:
|
|
|
|
|
+ logger.exception(
|
|
|
|
|
+ "discover videos worker 出现未捕获错误: biz_dt=%s",
|
|
|
|
|
+ resolved_biz_dt,
|
|
|
|
|
+ )
|
|
|
|
|
+ result["failed"] += 1
|
|
|
|
|
+ result["processed"] += 1
|
|
|
|
|
+ result["errors"].append({"error": str(exc)})
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ result["processed"] += 1
|
|
|
|
|
+ if item_result.get("skipped"):
|
|
|
|
|
+ result["skipped"] += 1
|
|
|
|
|
+ continue
|
|
|
|
|
+ if item_result.get("success"):
|
|
|
|
|
+ result["succeeded"] += 1
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ result["failed"] += 1
|
|
|
|
|
+ result["errors"].append(
|
|
|
|
|
+ {
|
|
|
|
|
+ "demand_grade_id": item_result.get("demand_grade_id"),
|
|
|
|
|
+ "demand_name": item_result.get("demand_name"),
|
|
|
|
|
+ "video_count": item_result.get("video_count"),
|
|
|
|
|
+ "run_id": item_result.get("run_id"),
|
|
|
|
|
+ "error": item_result.get("error"),
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ passed_videos = _count_passed_videos(resolved_biz_dt)
|
|
|
|
|
+ result["passed_videos"] = passed_videos
|
|
|
|
|
+ if passed_videos >= _DAILY_PASSED_VIDEO_LIMIT:
|
|
|
|
|
+ result["stopped_by_passed_video_limit"] = True
|
|
|
|
|
+ break
|
|
|
|
|
|
|
|
finished_at = datetime.now()
|
|
finished_at = datetime.now()
|
|
|
result["finished_at"] = finished_at.isoformat()
|
|
result["finished_at"] = finished_at.isoformat()
|