refactor(api): TOML 配置 SSOT、统一错误契约、Auth/事务加固与可观测性 (#33)
配置 SSOT(TOML + .env) 统一错误契约 Auth 与事务边界 Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client 可观测性(OpenTelemetry + LGTM)
This commit is contained in:
@@ -6,37 +6,26 @@ enqueue 失败不回滚已提交数据,仅记录日志;依赖后续触发或
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import threading
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, cast
|
||||
|
||||
import redis
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.logging import get_logger
|
||||
from app.core.memoir_pipeline_progress import merge_pipeline_run
|
||||
from app.core.memory_compaction_schedule import schedule_memory_compaction_run
|
||||
from app.core.redis_sync import get_sync_redis
|
||||
from app.features.memoir.constants import memoir
|
||||
from app.features.story.constants import story
|
||||
|
||||
logger = get_logger(__name__)
|
||||
_redis_client: redis.Redis | None = None
|
||||
_redis_lock = threading.Lock()
|
||||
|
||||
|
||||
def _story_image_enqueue_key(story_id: str) -> str:
|
||||
return f"enqueue:story-image:{story_id}"
|
||||
|
||||
|
||||
def _get_redis() -> redis.Redis:
|
||||
"""进程内复用单个 Redis 客户端,避免重复创建连接池。"""
|
||||
global _redis_client
|
||||
if _redis_client is None:
|
||||
with _redis_lock:
|
||||
if _redis_client is None:
|
||||
_redis_client = redis.from_url(
|
||||
settings.redis_url, decode_responses=True
|
||||
)
|
||||
return _redis_client
|
||||
def _get_redis():
|
||||
return get_sync_redis(decode_responses=True)
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -68,7 +57,7 @@ def enqueue_story_post_commit_effects(
|
||||
"""
|
||||
result = PostCommitResult()
|
||||
r = _get_redis()
|
||||
ttl = int(settings.story_image_enqueue_dedup_ttl)
|
||||
ttl = int(story.image_enqueue_dedup_ttl)
|
||||
|
||||
if need_image and story_ids:
|
||||
from app.tasks.story_image_tasks import (
|
||||
@@ -131,7 +120,7 @@ def enqueue_story_post_commit_effects(
|
||||
recompose_chapter as recompose_chapter_task,
|
||||
)
|
||||
|
||||
cd = int(settings.recompose_chapter_delay_seconds)
|
||||
cd = int(story.recompose_chapter_delay_seconds)
|
||||
for cid in sorted(chapter_ids):
|
||||
try:
|
||||
rkwargs: dict[str, Any] = {}
|
||||
@@ -201,13 +190,13 @@ def enqueue_story_post_commit_effects(
|
||||
)
|
||||
result.errors.append(f"compaction:{exc}")
|
||||
|
||||
if need_quality_pass and settings.memoir_quality_pass_enabled and story_ids:
|
||||
if need_quality_pass and memoir.quality_pass_enabled and story_ids:
|
||||
try:
|
||||
from app.tasks.memoir_quality_pass_tasks import (
|
||||
memoir_quality_pass as quality_pass_task,
|
||||
)
|
||||
|
||||
cd = int(settings.memoir_quality_pass_delay_seconds)
|
||||
cd = int(memoir.quality_pass_delay_seconds)
|
||||
qp_ar = cast(Any, quality_pass_task).apply_async(
|
||||
args=[user_id, sorted(story_ids), sorted(chapter_ids)],
|
||||
kwargs={"memoir_correlation_id": memoir_correlation_id},
|
||||
|
||||
Reference in New Issue
Block a user