This commit is contained in:
2026-04-05 05:10:17 +03:30
parent ec8e72737b
commit 6f098a1021
6 changed files with 457 additions and 6 deletions
+28 -3
View File
@@ -1,7 +1,8 @@
import time
from django.db import OperationalError, ProgrammingError
from django.db.models import QuerySet
from django.db.models import Case, IntegerField, QuerySet, Value, When
from farm_hub.models import FarmHub
@@ -39,6 +40,30 @@ def get_notifications_for_farm(*, farm: FarmHub, since_id=None) -> QuerySet[Farm
raise ValueError("Notifications table is not migrated.") from exc
def get_prioritized_notifications_for_farm(*, farm: FarmHub, since_id=None, limit=5) -> QuerySet[FarmNotification]:
try:
unread_queryset = get_notifications_for_farm(farm=farm, since_id=since_id).filter(is_read=False)
unread_count = unread_queryset.count()
if unread_count >= limit:
return unread_queryset[:limit]
fallback_limit = max(limit - unread_count, 0)
if fallback_limit == 0:
return unread_queryset
queryset = get_notifications_for_farm(farm=farm, since_id=since_id).annotate(
priority=Case(
When(is_read=False, then=Value(0)),
default=Value(1),
output_field=IntegerField(),
)
)
return queryset.order_by("priority", "created_at", "id")[:limit]
except (ProgrammingError, OperationalError) as exc:
raise ValueError("Notifications table is not migrated.") from exc
def mark_notifications_as_read(*, farm: FarmHub, slice_id: int) -> int:
try:
return FarmNotification.objects.filter(
@@ -50,10 +75,10 @@ def mark_notifications_as_read(*, farm: FarmHub, slice_id: int) -> int:
raise ValueError("Notifications table is not migrated.") from exc
def long_poll_notifications(*, farm: FarmHub, since_id=None, timeout_seconds=DEFAULT_POLL_TIMEOUT_SECONDS, interval_seconds=DEFAULT_POLL_INTERVAL_SECONDS):
def long_poll_notifications(*, farm: FarmHub, since_id=None, timeout_seconds=DEFAULT_POLL_TIMEOUT_SECONDS, interval_seconds=DEFAULT_POLL_INTERVAL_SECONDS, limit=5):
deadline = time.monotonic() + max(timeout_seconds, 0)
while True:
notifications = list(get_notifications_for_farm(farm=farm, since_id=since_id))
notifications = list(get_prioritized_notifications_for_farm(farm=farm, since_id=since_id, limit=limit))
if notifications:
return notifications
if time.monotonic() >= deadline: