feat: professionalize control plane and standalone delivery

This commit is contained in:
theshy
2026-04-07 10:46:30 +08:00
parent d0cf1fd0df
commit 862db502b0
100 changed files with 8313 additions and 1483 deletions

View File

@ -2,6 +2,11 @@ from __future__ import annotations
from datetime import datetime, timedelta, timezone
STEP_SETTINGS_GROUP = {
"publish": "publish",
"comment": "comment",
}
def parse_iso(value: str | None) -> datetime | None:
if not value:
@ -12,7 +17,14 @@ def parse_iso(value: str | None) -> datetime | None:
return None
def publish_retry_schedule_seconds(settings: dict[str, object]) -> list[int]:
def retry_schedule_seconds(
settings: dict[str, object],
*,
count_key: str,
backoff_key: str,
default_count: int,
default_backoff: int,
) -> list[int]:
raw_schedule = settings.get("retry_schedule_minutes")
if isinstance(raw_schedule, list):
schedule: list[int] = []
@ -21,25 +33,57 @@ def publish_retry_schedule_seconds(settings: dict[str, object]) -> list[int]:
schedule.append(item * 60)
if schedule:
return schedule
retry_count = settings.get("retry_count", 5)
retry_count = retry_count if isinstance(retry_count, int) and not isinstance(retry_count, bool) else 5
retry_count = settings.get(count_key, default_count)
retry_count = retry_count if isinstance(retry_count, int) and not isinstance(retry_count, bool) else default_count
retry_count = max(retry_count, 0)
retry_backoff = settings.get("retry_backoff_seconds", 300)
retry_backoff = retry_backoff if isinstance(retry_backoff, int) and not isinstance(retry_backoff, bool) else 300
retry_backoff = settings.get(backoff_key, default_backoff)
retry_backoff = retry_backoff if isinstance(retry_backoff, int) and not isinstance(retry_backoff, bool) else default_backoff
retry_backoff = max(retry_backoff, 0)
return [retry_backoff] * retry_count
def publish_retry_schedule_seconds(settings: dict[str, object]) -> list[int]:
return retry_schedule_seconds(
settings,
count_key="retry_count",
backoff_key="retry_backoff_seconds",
default_count=5,
default_backoff=300,
)
def comment_retry_schedule_seconds(settings: dict[str, object]) -> list[int]:
return retry_schedule_seconds(
settings,
count_key="max_retries",
backoff_key="base_delay_seconds",
default_count=5,
default_backoff=180,
)
def retry_meta_for_step(step, settings_by_group: dict[str, object]) -> dict[str, object] | None: # type: ignore[no-untyped-def]
if getattr(step, "status", None) != "failed_retryable" or getattr(step, "retry_count", 0) <= 0:
return None
if getattr(step, "step_name", None) != "publish":
step_name = getattr(step, "step_name", None)
settings_group = STEP_SETTINGS_GROUP.get(step_name)
if settings_group is None:
return None
group_settings = settings_by_group.get(settings_group, {})
if not isinstance(group_settings, dict):
group_settings = {}
if step_name == "publish":
schedule = publish_retry_schedule_seconds(group_settings)
elif step_name == "comment":
schedule = comment_retry_schedule_seconds(group_settings)
else:
return None
publish_settings = settings_by_group.get("publish", {})
if not isinstance(publish_settings, dict):
publish_settings = {}
schedule = publish_retry_schedule_seconds(publish_settings)
attempt_index = step.retry_count - 1
if attempt_index >= len(schedule):
return {