scheduler.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. """Compatibility facade over the durable pipeline control plane."""
  2. from __future__ import annotations
  3. from typing import Any
  4. from api.services.pipeline import get_run, pipeline_health
  5. from supply_infra.config import get_infra_settings
  6. from supply_infra.pipeline.dag import PIPELINE_STEPS
  7. from supply_infra.pipeline.dates import CHINA_TIMEZONE, next_schedule_china
  8. from supply_infra.pipeline.run_service import submit_pipeline_run
  9. from supply_infra.scheduler.constants import (
  10. AIGC_PUBLISH_JOB_ID,
  11. AIGC_PUBLISH_JOB_NAME,
  12. SUPPLY_PIPELINE_JOB_ID,
  13. SUPPLY_PIPELINE_JOB_NAME,
  14. )
  15. from supply_infra.scheduler.jobs.publish_videos_from_discovery import (
  16. publish_videos_from_discovery,
  17. )
  18. def list_triggerable_jobs() -> list[dict[str, Any]]:
  19. settings = get_infra_settings()
  20. return [
  21. {
  22. "id": SUPPLY_PIPELINE_JOB_ID,
  23. "name": SUPPLY_PIPELINE_JOB_NAME,
  24. "description": "提交严格门禁的 11 步持久化供给流水线(不含 AIGC 发布)",
  25. "accepts_biz_dt": True,
  26. "deprecated": False,
  27. "steps": [step.key for step in PIPELINE_STEPS],
  28. },
  29. {
  30. "id": AIGC_PUBLISH_JOB_ID,
  31. "name": AIGC_PUBLISH_JOB_NAME,
  32. "description": (
  33. "扫描未发布的 primary 候选并分发到 AIGC;"
  34. f"调度默认每 {settings.scheduler_aigc_publish_interval_minutes} 分钟执行"
  35. ),
  36. "accepts_biz_dt": True,
  37. "deprecated": False,
  38. "steps": [],
  39. },
  40. ]
  41. def run_scheduler_job(
  42. job_id: str,
  43. *,
  44. biz_dt: str | None = None,
  45. ) -> dict[str, Any]:
  46. if job_id == SUPPLY_PIPELINE_JOB_ID:
  47. return submit_pipeline_run(
  48. biz_dt=biz_dt,
  49. trigger_type="api",
  50. trigger_source="legacy_scheduler_api",
  51. ).to_dict()
  52. if job_id == AIGC_PUBLISH_JOB_ID:
  53. return publish_videos_from_discovery(
  54. biz_dt=biz_dt,
  55. skip_published=True,
  56. any_biz_dt=biz_dt is None,
  57. )
  58. raise KeyError(job_id)
  59. def get_scheduler_job_run(run_id: str) -> dict[str, Any] | None:
  60. return get_run(run_id)
  61. def run_supply_pipeline(*, biz_dt: str | None = None) -> dict[str, Any]:
  62. return run_scheduler_job(SUPPLY_PIPELINE_JOB_ID, biz_dt=biz_dt)
  63. def scheduler_status() -> dict[str, Any]:
  64. settings = get_infra_settings()
  65. health = pipeline_health()
  66. return {
  67. "enabled": settings.scheduler_enabled,
  68. "running": health["scheduler_running"],
  69. "embedded": False,
  70. "deprecated": True,
  71. "timezone": settings.scheduler_timezone,
  72. "jobs": [
  73. {
  74. "id": SUPPLY_PIPELINE_JOB_ID,
  75. "name": SUPPLY_PIPELINE_JOB_NAME,
  76. "next_run_time": next_schedule_china(settings=settings)
  77. .replace(tzinfo=CHINA_TIMEZONE)
  78. .isoformat(),
  79. },
  80. {
  81. "id": AIGC_PUBLISH_JOB_ID,
  82. "name": AIGC_PUBLISH_JOB_NAME,
  83. "interval_minutes": settings.scheduler_aigc_publish_interval_minutes,
  84. },
  85. ],
  86. **health,
  87. }