Blame view

translation/cache.py 3.7 KB
cd4ce66d   tangwang   trans logs
1
2
3
4
5
6
7
8
  """Shared translation cache utilities."""
  
  from __future__ import annotations
  
  import hashlib
  import logging
  from typing import Mapping, Optional
  
86d8358b   tangwang   config optimize
9
10
11
12
  try:
      import redis
  except ImportError:  # pragma: no cover - runtime fallback for minimal envs
      redis = None  # type: ignore[assignment]
cd4ce66d   tangwang   trans logs
13
  
86d8358b   tangwang   config optimize
14
  from config.loader import get_app_config
cd4ce66d   tangwang   trans logs
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  
  logger = logging.getLogger(__name__)
  
  
  class TranslationCache:
      """Redis-backed cache shared by all translation capabilities."""
  
      def __init__(self, config: Mapping[str, object]) -> None:
          self.ttl_seconds = int(config["ttl_seconds"])
          self.sliding_expiration = bool(config["sliding_expiration"])
          self.redis_client = self._init_redis_client()
  
      @property
      def available(self) -> bool:
          return self.redis_client is not None
  
      def build_key(self, *, model: str, target_lang: str, source_text: str) -> str:
          normalized_model = str(model or "").strip().lower()
          normalized_target_lang = str(target_lang or "").strip().lower()
          text = str(source_text or "")
          text_prefix = text[:4]
          digest = hashlib.sha256(text.encode("utf-8")).hexdigest()
          return f"trans:{normalized_model}:{normalized_target_lang}:{text_prefix}{digest}"
  
8140e942   tangwang   translator model ...
39
40
41
42
43
44
45
      def get(
          self,
          *,
          model: str,
          target_lang: str,
          source_text: str
      ) -> Optional[str]:
cd4ce66d   tangwang   trans logs
46
47
48
49
50
51
          if self.redis_client is None:
              return None
          key = self.build_key(model=model, target_lang=target_lang, source_text=source_text)
          try:
              value = self.redis_client.get(key)
              logger.info(
14e67b71   tangwang   分句后的 batching 现在是...
52
                  "Translation cache %s | text_len=%s key=%s",
cd4ce66d   tangwang   trans logs
53
                  "hit" if value is not None else "miss",
cd4ce66d   tangwang   trans logs
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
                  len(str(source_text or "")),
                  key,
              )
              if value and self.sliding_expiration:
                  self.redis_client.expire(key, self.ttl_seconds)
              return value
          except Exception as exc:
              logger.warning("Redis get translation cache failed: %s", exc)
              return None
  
      def set(self, *, model: str, target_lang: str, source_text: str, translated_text: str) -> None:
          if self.redis_client is None:
              return
          key = self.build_key(model=model, target_lang=target_lang, source_text=source_text)
          try:
              self.redis_client.setex(key, self.ttl_seconds, translated_text)
              logger.info(
14e67b71   tangwang   分句后的 batching 现在是...
71
                  "Translation cache write | text_len=%s result_len=%s ttl_seconds=%s key=%s",
cd4ce66d   tangwang   trans logs
72
73
74
75
76
77
78
79
80
81
                  len(str(source_text or "")),
                  len(str(translated_text or "")),
                  self.ttl_seconds,
                  key,
              )
          except Exception as exc:
              logger.warning("Redis set translation cache failed: %s", exc)
  
      @staticmethod
      def _init_redis_client() -> Optional[redis.Redis]:
86d8358b   tangwang   config optimize
82
83
84
85
          if redis is None:
              logger.warning("redis package is not installed; translation cache disabled")
              return None
          redis_config = get_app_config().infrastructure.redis
cd4ce66d   tangwang   trans logs
86
87
          try:
              client = redis.Redis(
86d8358b   tangwang   config optimize
88
89
                  host=redis_config.host,
                  port=redis_config.port,
778c299a   tangwang   测试环境redis配置
90
                  db=redis_config.snapshot_db,
86d8358b   tangwang   config optimize
91
                  password=redis_config.password,
cd4ce66d   tangwang   trans logs
92
                  decode_responses=True,
86d8358b   tangwang   config optimize
93
94
95
                  socket_timeout=redis_config.socket_timeout,
                  socket_connect_timeout=redis_config.socket_connect_timeout,
                  retry_on_timeout=redis_config.retry_on_timeout,
cd4ce66d   tangwang   trans logs
96
97
98
99
100
101
102
                  health_check_interval=10,
              )
              client.ping()
              return client
          except Exception as exc:
              logger.warning("Failed to initialize translation redis cache: %s", exc)
              return None