v1.5.0: entry-dedup in één query + conditional get (ETag/Last-Modified)
- filter_entries: één SELECT per feed i.p.v. per-entry EXISTS (1082 queries → 20) - feed.etag/last_modified (migratie v9); parse_feed stuurt If-None-Match/If-Modified-Since, 304 → None - _poll_once telt unchanged (304-feeds); summary-regel uitgebreid met unchanged - _poll_feeds re-raised CancelledError (reload-stapeling duplicaten) + handler-cleanup
This commit is contained in:
parent
1f92b38ba6
commit
a03f76ca83
4 changed files with 59 additions and 25 deletions
|
|
@ -64,6 +64,8 @@ class Feed:
|
|||
|
||||
next_retry: int = 0
|
||||
error_count: int = 0
|
||||
etag: str = ""
|
||||
last_modified: str = ""
|
||||
|
||||
subscriptions: list[Subscription] = attr.ib(factory=lambda: [])
|
||||
|
||||
|
|
@ -119,7 +121,7 @@ class DBManager:
|
|||
|
||||
async def get_feeds(self) -> list[Feed]:
|
||||
q = """
|
||||
SELECT id, url, title, subtitle, link, next_retry, error_count,
|
||||
SELECT id, url, title, subtitle, link, next_retry, error_count, etag, last_modified,
|
||||
room_id, user_id, notification_template, send_notice
|
||||
FROM feed INNER JOIN subscription ON feed.id = subscription.feed_id
|
||||
"""
|
||||
|
|
@ -135,25 +137,19 @@ class DBManager:
|
|||
|
||||
async def get_feeds_by_room(self, room_id: RoomID) -> list[tuple[Feed, UserID]]:
|
||||
q = """
|
||||
SELECT id, url, title, subtitle, link, next_retry, error_count, user_id FROM feed
|
||||
SELECT id, url, title, subtitle, link, next_retry, error_count, etag, last_modified,
|
||||
user_id FROM feed
|
||||
INNER JOIN subscription ON feed.id = subscription.feed_id AND subscription.room_id = $1
|
||||
"""
|
||||
rows = await self.db.fetch(q, room_id)
|
||||
return [(Feed.from_row(row), row["user_id"]) for row in rows]
|
||||
|
||||
async def filter_entries(self, feed_id: int, entries: dict[str, Entry]) -> None:
|
||||
entry_keys = list(entries.keys())
|
||||
if not entry_keys:
|
||||
if not entries:
|
||||
return
|
||||
async with self.db.acquire() as conn:
|
||||
for key in entry_keys:
|
||||
exists = await conn.fetchval(
|
||||
"SELECT EXISTS(SELECT 1 FROM entry WHERE feed_id = $1 AND id = $2)",
|
||||
feed_id,
|
||||
key,
|
||||
)
|
||||
if exists:
|
||||
del entries[key]
|
||||
existing = await self.db.fetch("SELECT id FROM entry WHERE feed_id = $1", feed_id)
|
||||
for row in existing:
|
||||
entries.pop(row["id"], None)
|
||||
|
||||
async def add_entries(self, entries: list[Entry], override_feed_id: int | None = None) -> None:
|
||||
if not entries:
|
||||
|
|
@ -174,14 +170,14 @@ class DBManager:
|
|||
await conn.executemany(q, records)
|
||||
|
||||
async def get_feed_by_url(self, url: str) -> Feed | None:
|
||||
q = "SELECT id, url, title, subtitle, link, next_retry, error_count FROM feed WHERE url=$1"
|
||||
q = "SELECT id, url, title, subtitle, link, next_retry, error_count, etag, last_modified FROM feed WHERE url=$1"
|
||||
return Feed.from_row(await self.db.fetchrow(q, url))
|
||||
|
||||
async def get_subscription(
|
||||
self, feed_id: int, room_id: RoomID
|
||||
) -> tuple[Subscription | None, Feed | None]:
|
||||
q = """
|
||||
SELECT id, url, title, subtitle, link, next_retry, error_count,
|
||||
SELECT id, url, title, subtitle, link, next_retry, error_count, etag, last_modified,
|
||||
room_id, user_id, notification_template, send_notice
|
||||
FROM feed LEFT JOIN subscription ON feed.id = subscription.feed_id AND room_id = $2
|
||||
WHERE feed.id = $1
|
||||
|
|
@ -206,6 +202,10 @@ class DBManager:
|
|||
q = "UPDATE feed SET error_count = $2, next_retry = $3 WHERE id = $1"
|
||||
await self.db.execute(q, info.id, error_count, next_retry)
|
||||
|
||||
async def set_feed_headers(self, info: Feed, etag: str, last_modified: str) -> None:
|
||||
q = "UPDATE feed SET etag = $2, last_modified = $3 WHERE id = $1"
|
||||
await self.db.execute(q, info.id, etag, last_modified)
|
||||
|
||||
async def subscribe(
|
||||
self,
|
||||
feed_id: int,
|
||||
|
|
|
|||
Loading…
Reference in a new issue