trace/services/notify-gateway/gateway/delivery_store.py
Lee 19afaffbb7
All checks were successful
Java Maven 3.9.9 & JDK 26 CI/CD Pipeline / build-and-deploy (push) Successful in 3m22s
feat: add shared notification gateway
2026-09-07 17:50:25 +08:00

49 lines
1.7 KiB
Python

import aiosqlite
SCHEMA = """
PRAGMA journal_mode=WAL;
PRAGMA synchronous=FULL;
CREATE TABLE IF NOT EXISTS deliveries (
idempotency_key TEXT NOT NULL,
channel TEXT NOT NULL,
delivered INTEGER NOT NULL DEFAULT 0,
attempts INTEGER NOT NULL DEFAULT 0,
last_error TEXT,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (idempotency_key, channel)
);
"""
class DeliveryStore:
def __init__(self, path: str) -> None:
self.path = path
async def init(self) -> None:
async with aiosqlite.connect(self.path) as db:
await db.executescript(SCHEMA)
await db.commit()
async def delivered(self, key: str, channel: str) -> bool:
async with aiosqlite.connect(self.path) as db:
row = await (await db.execute(
"SELECT delivered FROM deliveries WHERE idempotency_key=? AND channel=?",
(key, channel),
)).fetchone()
return bool(row and row[0])
async def record(self, key: str, channel: str, ok: bool, error: str = "") -> None:
async with aiosqlite.connect(self.path) as db:
await db.execute(
"""INSERT INTO deliveries(idempotency_key,channel,delivered,attempts,last_error)
VALUES(?,?,?,?,?)
ON CONFLICT(idempotency_key,channel) DO UPDATE SET
delivered=MAX(deliveries.delivered, excluded.delivered),
attempts=deliveries.attempts+1,
last_error=CASE WHEN excluded.delivered=1 THEN NULL ELSE excluded.last_error END,
updated_at=CURRENT_TIMESTAMP""",
(key, channel, int(ok), 1, error[:500] or None),
)
await db.commit()