resolve various reviews

This commit is contained in:
Petitminion 2023-06-26 14:13:50 +02:00
parent 281993c903
commit 601144edf8
5 changed files with 33 additions and 32 deletions

View File

@ -463,8 +463,6 @@ class TrackQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet):
return self.exclude(pk__in=matches)
def with_playable_uploads(self, actor):
if not actor:
uploads = Upload.objects.filter(library__privacy_level="public")
uploads = Upload.objects.playable_by(actor)
return self.prefetch_related(
models.Prefetch("uploads", queryset=uploads, to_attr="playable_uploads")

View File

@ -1,6 +1,7 @@
import datetime
import json
import logging
import pickle
import random
from typing import List, Optional, Tuple
@ -124,7 +125,10 @@ class SessionRadio(SimpleRadio):
def cache_batch_radio_track(self, **kwargs):
BATCH_SIZE = 100
# get cached RadioTracks if any
old_evaluated_radio_tracks = cache.get(f"radiosessiontracks{self.session.id}")
try :
cached_evaluated_radio_tracks = pickle.loads(cache.get(f"radiosessiontracks{self.session.id}"))
except TypeError :
cached_evaluated_radio_tracks = None
# get the queryset and apply filters
kwargs.update(self.get_queryset_kwargs())
@ -138,24 +142,23 @@ class SessionRadio(SimpleRadio):
# select a random batch of the qs
sliced_queryset = queryset.order_by("?")[:BATCH_SIZE]
if len(sliced_queryset) == 0 and not old_evaluated_radio_tracks:
if len(sliced_queryset) <= 0 and not cached_evaluated_radio_tracks:
raise ValueError("No more radio candidates")
if len(sliced_queryset) > 0:
# create the radio session tracks into db in bulk
radio_tracks = self.session.add(sliced_queryset)
# create the radio session tracks into db in bulk
radio_tracks = self.session.add(sliced_queryset)
# evaluate the queryset to save it in cache
evaluated_radio_tracks = [t for t in radio_tracks]
if old_evaluated_radio_tracks is not None:
evaluated_radio_tracks.append(old_evaluated_radio_tracks)
logger.info(
f"Setting redis cache for radio generation with radio id {self.session.id}"
)
cache.set(
f"radiosessiontracks{self.session.id}", evaluated_radio_tracks, 3600
)
cache.set(f"radioqueryset{self.session.id}", sliced_queryset, 3600)
# evaluate the queryset to save it in cache
if cached_evaluated_radio_tracks is not None:
radio_tracks = [t for t in radio_tracks]
radio_tracks.extend(cached_evaluated_radio_tracks)
logger.info(
f"Setting redis cache for radio generation with radio id {self.session.id}"
)
cache.set(
f"radiosessiontracks{self.session.id}", pickle.dumps(radio_tracks), 3600
)
cache.set(f"radioqueryset{self.session.id}", sliced_queryset, 3600)
return sliced_queryset
@ -170,7 +173,8 @@ class SessionRadio(SimpleRadio):
return queryset
def get_choices_v2(self, quantity, **kwargs):
if cached_radio_tracks := cache.get(f"radiosessiontracks{self.session.id}"):
if cache.get(f"radiosessiontracks{self.session.id}") :
cached_radio_tracks = pickle.loads(cache.get(f"radiosessiontracks{self.session.id}"))
logger.info("Using redis cache for radio generation")
radio_tracks = cached_radio_tracks
if len(radio_tracks) < quantity:

View File

@ -5,7 +5,7 @@ from . import views
router = routers.OptionalSlashRouter()
router.register(r"sessions", views.RadioSessionViewSet, "sessions")
router.register(r"radios", views.RadioViewSet, "radios")
router.register(r"tracks", views.RadioSessionTrackViewSet, "tracks")
router.register(r"tracks", views.V1_RadioSessionTrackViewSet, "tracks")
urlpatterns = router.urls

View File

@ -1,3 +1,5 @@
import pickle
from django.core.cache import cache
from django.db.models import Q
from drf_spectacular.utils import extend_schema
@ -123,7 +125,7 @@ class RadioSessionViewSet(
return context
class RadioSessionTrackViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
class V1_RadioSessionTrackViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = serializers.RadioSessionTrackSerializer
queryset = models.RadioSessionTrack.objects.all()
permission_classes = []
@ -206,9 +208,8 @@ class RadioSessionTracksViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet
)
# self.perform_create(serializer)
# dirty override here, since we use a different serializer for creation and detail
evaluated_radio_tracks = cache.get(f"radiosessiontracks{session.id}")
evaluated_radio_tracks = pickle.loads(cache.get(f"radiosessiontracks{session.id}"))
batch = evaluated_radio_tracks[:count]
serializer = self.serializer_class(
data=batch,
context=self.get_serializer_context(),
@ -222,9 +223,9 @@ class RadioSessionTracksViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet
radiotrack.played = True
RadioSessionTrack.objects.bulk_update(batch, ["played"])
# delete the tracks we send from the cache
# delete the tracks we sent from the cache
new_cached_radiotracks = evaluated_radio_tracks[count:]
cache.set(f"radiosessiontracks{session.id}", new_cached_radiotracks)
cache.set(f"radiosessiontracks{session.id}", pickle.dumps(new_cached_radiotracks))
return Response(
serializer.data, status=status.HTTP_201_CREATED, headers=headers

View File

@ -1,5 +1,6 @@
import json
import logging
import pickle
import random
import pytest
@ -103,8 +104,7 @@ def test_can_get_choices_for_custom_radio(factories):
choices = session.radio.get_choices(filter_playable=False)
expected = [t.pk for t in tracks]
for t in list(choices.values_list("id", flat=True)):
assert t in expected
assert list(choices.values_list("id", flat=True)) == expected
def test_cannot_start_custom_radio_if_not_owner_or_not_public(factories):
@ -423,8 +423,7 @@ def test_get_choices_for_custom_radio_exclude_artist(factories):
choices = session.radio.get_choices(filter_playable=False)
expected = [u.track.pk for u in included_uploads]
for t in list(choices.values_list("id", flat=True)):
assert t in expected
assert list(choices.values_list("id", flat=True)) == expected
def test_get_choices_for_custom_radio_exclude_tag(factories):
@ -442,8 +441,7 @@ def test_get_choices_for_custom_radio_exclude_tag(factories):
choices = session.radio.get_choices(filter_playable=False)
expected = [u.track.pk for u in included_uploads]
for t in list(choices.values_list("id", flat=True)):
assert t in expected
assert list(choices.values_list("id", flat=True)) == expected
def test_can_start_custom_multiple_radio_from_api(api_client, factories):
@ -527,7 +525,7 @@ def test_can_cache_radio_track(factories):
session = radio.start_session(user)
picked = session.radio.pick_many_v2(quantity=1, filter_playable=False)
assert len(picked) == 1
for t in cache.get(f"radiosessiontracks{session.id}"):
for t in pickle.loads(cache.get(f"radiosessiontracks{session.id}")):
assert t.track in uploads