cicboy's picture
update cache.py, google_maps_tool.py and route_planner_tool.py
ace8cdd
# utils/cache.py
import json, sqlite3, time
import threading
from contextlib import contextmanager
from typing import Any, Optional
class SQLiteCache:
def __init__(
self,
path: str = "/tmp/cache.sqlite",
default_ttl_seconds: int = 3600,
sqlite_timeout_seconds: int = 10,
busy_timeout_ms: int = 5000,
use_wal: bool = True,
):
self.path = path
self.default_ttl_seconds = default_ttl_seconds
self.sqlite_timeout_seconds = sqlite_timeout_seconds
self.busy_timeout_ms = busy_timeout_ms
self.use_wal = use_wal
self._lock = threading.Lock()
self._init_db()
def _connect(self) -> sqlite3.Connection:
con = sqlite3.connect(self.path, timeout=self.sqlite_timeout_seconds)
if self.use_wal:
con.execute("PRAGMA journal_mode=WAL;")
con.execute("PRAGMA synchronous=NORMAL;")
con.execute(f"PRAGMA busy_timeout={self.busy_timeout_ms};")
return con
def _init_db(self):
with self._connect() as con:
con.execute("""
CREATE TABLE IF NOT EXISTS cache (
k TEXT PRIMARY KEY,
v TEXT NOT NULL,
expires_at INTEGER NOT NULL
)
""")
con.commit()
def get(self, key: str) -> Optional[Any]:
now = int(time.time())
with self._connect() as con:
row = con.execute("SELECT v, expires_at FROM cache WHERE k=?", (key,)).fetchone()
if not row:
return None
v, expires_at = row
if expires_at < now:
self.delete(key)
return None
try:
return json.loads(v)
except Exception:
self.delete(key)
return None
def set(self, key: str, value: Any, ttl_seconds: Optional[int] = None) -> None:
ttl = self.default_ttl_seconds if ttl_seconds is None else int(ttl_seconds)
expires_at = int(time.time()) + ttl
payload = json.dumps(value)
with self._lock:
with self._connect() as con:
con.execute(
"INSERT OR REPLACE INTO cache (k, v, expires_at) VALUES (?, ?, ?)",
(key, payload, expires_at)
)
con.commit()
def delete(self, key: str) -> None:
with self._lock:
with self._connect() as con:
con.execute("DELETE FROM cache WHERE k=?", (key,))
con.commit()
def set_negative(self, key: str, ttl_seconds: int = 600, marker: str = "__no_route__") -> None:
self.set(key, {marker: True}, ttl_seconds=ttl_seconds)