Refactor code for improved readability and consistency

- Cleaned up whitespace and formatting in various files including http.py, language.py, logger.py, safe_exec.py, and SQL migration scripts.
- Consolidated import statements and removed unnecessary blank lines.
- Updated logging configuration for better clarity.
- Enhanced the safe execution code with improved error handling and logging.
- Removed commented-out code and unnecessary variables in backfill_zero_trades.py and other scripts.
- Added a pyproject.toml for Ruff and Vulture configuration.
- Introduced requirements-dev.txt for development dependencies.
- Removed commented-out stock entries in init.sql for cleaner migration scripts.
This commit is contained in:
dienakdz
2026-04-09 14:30:51 +07:00
parent 103055b3df
commit 87f2845483
157 changed files with 19026 additions and 17773 deletions
@@ -13,13 +13,12 @@ characteristic:
3. Partition management by data type
"""
import time
import logging
from typing import Dict, Any, Optional, List
from collections import OrderedDict
from dataclasses import dataclass, field
from datetime import datetime
import threading
import time
from collections import OrderedDict
from dataclasses import dataclass
from typing import Any, Dict, Optional
logger = logging.getLogger(__name__)
@@ -27,15 +26,16 @@ logger = logging.getLogger(__name__)
@dataclass
class CacheEntry:
"""cache entry"""
data: Any
timestamp: float
ttl: float
hit_count: int = 0
def is_expired(self) -> bool:
"""Check if expired"""
return time.time() - self.timestamp > self.ttl
def age(self) -> float:
"""Return cache age (seconds)"""
return time.time() - self.timestamp
@@ -44,34 +44,34 @@ class CacheEntry:
class DataCache:
"""
Data Cache Manager
characteristic:
- TTL expiration mechanism
- Maximum capacity limit
- LRU elimination strategy
- Thread safety
"""
def __init__(
self,
name: str = "default",
default_ttl: float = 600.0, # Default 10 minutes
max_size: int = 1000 # Maximum number of cache entries
max_size: int = 1000, # Maximum number of cache entries
):
self.name = name
self.default_ttl = default_ttl
self.max_size = max_size
self._cache: OrderedDict[str, CacheEntry] = OrderedDict()
self._lock = threading.RLock()
# Statistics
self._hits = 0
self._misses = 0
def get(self, key: str) -> Optional[Any]:
"""
Get cached data
Returns:
Cached data, returns None if it does not exist or has expired.
"""
@@ -79,33 +79,28 @@ class DataCache:
if key not in self._cache:
self._misses += 1
return None
entry = self._cache[key]
# Check if expired
if entry.is_expired():
del self._cache[key]
self._misses += 1
logger.debug(f"[cache] {self.name}:{key} expired and was removed")
return None
# Update access order (LRU)
self._cache.move_to_end(key)
entry.hit_count += 1
self._hits += 1
logger.debug(f"[cache hit] {self.name}:{key} (age: {entry.age():.0f}s/{entry.ttl:.0f}s)")
return entry.data
def set(
self,
key: str,
data: Any,
ttl: Optional[float] = None
) -> None:
def set(self, key: str, data: Any, ttl: Optional[float] = None) -> None:
"""
Set cache data
Args:
key: cache key
data: cache data
@@ -116,16 +111,12 @@ class DataCache:
while len(self._cache) >= self.max_size:
oldest_key, _ = self._cache.popitem(last=False)
logger.debug(f"[cache] {self.name} reached capacity, evicted: {oldest_key}")
actual_ttl = ttl if ttl is not None else self.default_ttl
self._cache[key] = CacheEntry(
data=data,
timestamp=time.time(),
ttl=actual_ttl
)
self._cache[key] = CacheEntry(data=data, timestamp=time.time(), ttl=actual_ttl)
logger.debug(f"[cache update] {self.name}:{key} TTL={actual_ttl}s")
def delete(self, key: str) -> bool:
"""Delete cache entry"""
with self._lock:
@@ -134,7 +125,7 @@ class DataCache:
logger.debug(f"[cache] {self.name}:{key} deleted")
return True
return False
def clear(self) -> int:
"""Clear cache"""
with self._lock:
@@ -142,35 +133,32 @@ class DataCache:
self._cache.clear()
logger.info(f"[cache] {self.name} cleared {count} records")
return count
def cleanup_expired(self) -> int:
"""Clean up expired entries"""
with self._lock:
expired_keys = [
key for key, entry in self._cache.items()
if entry.is_expired()
]
expired_keys = [key for key, entry in self._cache.items() if entry.is_expired()]
for key in expired_keys:
del self._cache[key]
if expired_keys:
logger.debug(f"[cache] {self.name} cleaned {len(expired_keys)} expired records")
return len(expired_keys)
def stats(self) -> Dict[str, Any]:
"""Get cache statistics"""
with self._lock:
total_requests = self._hits + self._misses
hit_rate = self._hits / total_requests if total_requests > 0 else 0
return {
'name': self.name,
'size': len(self._cache),
'max_size': self.max_size,
'hits': self._hits,
'misses': self._misses,
'hit_rate': f"{hit_rate:.1%}",
'default_ttl': self.default_ttl
"name": self.name,
"size": len(self._cache),
"max_size": self.max_size,
"hits": self._hits,
"misses": self._misses,
"hit_rate": f"{hit_rate:.1%}",
"default_ttl": self.default_ttl,
}
@@ -182,21 +170,21 @@ class DataCache:
_realtime_cache = DataCache(
name="realtime",
default_ttl=1200.0, # 20 minutes
max_size=6000
max_size=6000,
)
# K-line data caching (5 minutes TTL, caching on demand)
_kline_cache = DataCache(
name="kline",
default_ttl=300.0, # 5 minutes
max_size=500 # Up to 500 trading pairs
default_ttl=300.0, # 5 minutes
max_size=500, # Up to 500 trading pairs
)
# Stock basic information cache (1 day TTL)
_stock_info_cache = DataCache(
name="stock_info",
default_ttl=86400.0, # 24 hours
max_size=6000
max_size=6000,
)
@@ -215,15 +203,10 @@ def get_stock_info_cache() -> DataCache:
return _stock_info_cache
def generate_kline_cache_key(
symbol: str,
timeframe: str,
limit: int,
before_time: Optional[int] = None
) -> str:
def generate_kline_cache_key(symbol: str, timeframe: str, limit: int, before_time: Optional[int] = None) -> str:
"""
Generate K-line cache key
Format: symbol:timeframe:limit[:before_time]
"""
key = f"{symbol}:{timeframe}:{limit}"