Files
ewoooc/services/pchome_growth_yahoo_scheduler_task.py
ogt 4670f80f98
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
feat(growth): automate Yahoo same-item offer canary
2026-07-15 12:43:24 +08:00

127 lines
4.7 KiB
Python

"""Scheduler adapter for the Yahoo public-offer reconciliation lane."""
from __future__ import annotations
import logging
import os
from datetime import datetime, timedelta, timezone
TAIPEI_TZ = timezone(timedelta(hours=8))
def run_scheduled_pchome_growth_yahoo_backfill(*, save_stats):
"""Bounded Yahoo public-offer reconciliation with canary and readback."""
try:
from config import DATABASE_PATH
from sqlalchemy import create_engine
from services.yahoo_shopping_public_offer_service import (
run_pchome_growth_yahoo_backfill,
)
now_str = datetime.now(TAIPEI_TZ).strftime("%Y-%m-%d %H:%M")
limit = max(
1,
min(int(os.getenv("PCHOME_GROWTH_YAHOO_BACKFILL_LIMIT", "8")), 20),
)
logging.info(
"[Scheduler] [PChomeGrowthYahooBackfill] starting | %s | limit=%s",
now_str,
limit,
)
engine = create_engine(DATABASE_PATH)
try:
result = run_pchome_growth_yahoo_backfill(engine, limit=limit)
finally:
engine.dispose()
data = result.get("data") or {}
sync_result = data.get("external_offer_sync") or {}
post_verifier = data.get("post_verifier") or {}
activation = data.get("source_activation") or {}
artifact = data.get("artifact_receipt") or {}
identity = data.get("identity") or {}
terminal_status = str(data.get("terminal_status") or "")
stats = {
"status": (
"Success"
if result.get("success") and terminal_status.startswith("verified")
else "Degraded"
if terminal_status.startswith(("degraded", "partial"))
else "Failed"
if not result.get("success")
else "Skipped"
),
"trace_id": identity.get("trace_id"),
"run_id": identity.get("run_id"),
"work_item_id": identity.get("work_item_id"),
"terminal_status": terminal_status,
"next_machine_action": data.get("next_machine_action"),
"scanned_products": data.get("scanned_products", 0),
"candidate_count": data.get("candidate_count", 0),
"auto_compare_count": data.get("auto_compare_count", 0),
"review_count": data.get("review_count", 0),
"written_count": sync_result.get("written_count", 0),
"readback_pass_count": post_verifier.get("readback_pass_count", 0),
"post_verifier_status": post_verifier.get("status"),
"source_activation_status": activation.get("status"),
"source_activated": bool(activation.get("applied")),
"artifact_status": artifact.get("status"),
"artifact_sha256": artifact.get("receipt_sha256"),
"message": result.get("message"),
}
logging.info(
"[Scheduler] [PChomeGrowthYahooBackfill] completed | "
"terminal=%s scanned=%s candidates=%s verified=%s written=%s "
"readback=%s activated=%s artifact=%s",
stats["terminal_status"],
stats["scanned_products"],
stats["candidate_count"],
stats["auto_compare_count"],
stats["written_count"],
stats["readback_pass_count"],
stats["source_activated"],
stats["artifact_status"],
)
save_stats("pchome_growth_yahoo_backfill", stats)
return result
except Exception as error:
import traceback as _tb
logging.error(
"[Scheduler] [PChomeGrowthYahooBackfill] task failed | Error: %s",
error,
exc_info=True,
)
save_stats(
"pchome_growth_yahoo_backfill",
{"status": "Failed", "error": str(error)},
)
try:
from services.event_router import notify_failure
notify_failure(
task_name="run_pchome_growth_yahoo_backfill_task",
error=error,
source="Scheduler.PChomeGrowthYahooBackfill",
event_type="pchome_growth_yahoo_backfill_failure",
priority="P2",
title="PChome 高業績商品 Yahoo 公開來源補齊異常",
trace=_tb.format_exc(),
)
except Exception as router_error:
logging.error(
"[Scheduler] [PChomeGrowthYahooBackfill] event_router failed: %s",
router_error,
)
return {
"success": False,
"message": str(error),
"data": {"terminal_status": "failed_with_safe_retry"},
}
__all__ = ["run_scheduled_pchome_growth_yahoo_backfill"]