|
|
@@ -1,5 +1,6 @@
|
|
|
from __future__ import annotations
|
|
|
|
|
|
+import os
|
|
|
import threading
|
|
|
|
|
|
try:
|
|
|
@@ -12,22 +13,29 @@ from .bitstamp import BitstampClient
|
|
|
from .bitstamp_fx import load_eur_usd
|
|
|
|
|
|
BITSTAMP_BASE_URL = "https://www.bitstamp.net"
|
|
|
-# Live trading reads should refresh quickly, stale fallback is only a short safety net.
|
|
|
-BALANCE_CACHE_TTL_SECONDS = 5
|
|
|
-ACCOUNT_INFO_CACHE_TTL_SECONDS = 5
|
|
|
+# Live trading reads should refresh quickly, but not so often that Bitstamp trips a breaker.
|
|
|
+BALANCE_CACHE_TTL_MS = 1200
|
|
|
+ACCOUNT_INFO_CACHE_TTL_MS = 1200
|
|
|
FEES_CACHE_TTL_SECONDS = 10 * 60
|
|
|
-STALE_CACHE_TTL_SECONDS = 30
|
|
|
+STALE_CACHE_TTL_SECONDS = 2
|
|
|
_CACHE_LOCKS: dict[str, threading.Lock] = {}
|
|
|
_CACHE_LOCKS_GUARD = threading.Lock()
|
|
|
_BITSTAMP_CLIENTS: dict[str, BitstampClient] = {}
|
|
|
_BITSTAMP_CLIENTS_GUARD = threading.Lock()
|
|
|
|
|
|
|
|
|
-def _ttl_from_env(name: str, default_seconds: int) -> int:
|
|
|
+def _ttl_from_env_ms(name: str, default_ms: int, *, legacy_seconds_name: str | None = None) -> float:
|
|
|
try:
|
|
|
- return max(int(__import__("os").getenv(name, str(default_seconds))), 0)
|
|
|
+ raw = os.getenv(name)
|
|
|
+ if raw is not None:
|
|
|
+ return max(float(raw) / 1000.0, 0.0)
|
|
|
+ if legacy_seconds_name:
|
|
|
+ legacy_raw = os.getenv(legacy_seconds_name)
|
|
|
+ if legacy_raw is not None:
|
|
|
+ return max(float(legacy_raw), 0.0)
|
|
|
+ return max(float(default_ms) / 1000.0, 0.0)
|
|
|
except Exception:
|
|
|
- return default_seconds
|
|
|
+ return max(float(default_ms) / 1000.0, 0.0)
|
|
|
|
|
|
|
|
|
def _cache_lock(cache_key: str) -> threading.Lock:
|
|
|
@@ -217,7 +225,15 @@ def fetch_account_balance(account_id: str) -> dict:
|
|
|
normalized = _normalize_account_balances_payload(payload, account_id)
|
|
|
|
|
|
result = {"source": "bitstamp", "cached": False, "balances": normalized, "payload": payload}
|
|
|
- repo.cache_put(cache_key, result, _ttl_from_env("BITSTAMP_BALANCE_CACHE_TTL_SECONDS", BALANCE_CACHE_TTL_SECONDS))
|
|
|
+ repo.cache_put(
|
|
|
+ cache_key,
|
|
|
+ result,
|
|
|
+ _ttl_from_env_ms(
|
|
|
+ "BITSTAMP_BALANCE_CACHE_TTL_MS",
|
|
|
+ BALANCE_CACHE_TTL_MS,
|
|
|
+ legacy_seconds_name="BITSTAMP_BALANCE_CACHE_TTL_SECONDS",
|
|
|
+ ),
|
|
|
+ )
|
|
|
repo.cache_put(_stale_key(cache_key), result, STALE_CACHE_TTL_SECONDS)
|
|
|
return result
|
|
|
|
|
|
@@ -284,7 +300,15 @@ def fetch_account_info(account_id: str) -> dict:
|
|
|
"raw_balance": balance["payload"],
|
|
|
}
|
|
|
|
|
|
- repo.cache_put(cache_key, result, _ttl_from_env("BITSTAMP_ACCOUNT_INFO_CACHE_TTL_SECONDS", ACCOUNT_INFO_CACHE_TTL_SECONDS))
|
|
|
+ repo.cache_put(
|
|
|
+ cache_key,
|
|
|
+ result,
|
|
|
+ _ttl_from_env_ms(
|
|
|
+ "BITSTAMP_ACCOUNT_INFO_CACHE_TTL_MS",
|
|
|
+ ACCOUNT_INFO_CACHE_TTL_MS,
|
|
|
+ legacy_seconds_name="BITSTAMP_ACCOUNT_INFO_CACHE_TTL_SECONDS",
|
|
|
+ ),
|
|
|
+ )
|
|
|
repo.cache_put(_stale_key(cache_key), result, STALE_CACHE_TTL_SECONDS)
|
|
|
return result
|
|
|
|