feat: professionalize control plane and standalone delivery
This commit is contained in:
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user