UPDATE
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user