From f6492a70dfedd2be4268a00b7cc2539a38859300 Mon Sep 17 00:00:00 2001 From: Jim Driessen Date: Sun, 24 Sep 2017 01:02:52 +0200 Subject: [PATCH] Fix race condition when requesting songs, causing them to get the same order value. --- .../0004_remove_playlistsong_order.py | 19 +++++++++++ marietje/queues/models.py | 34 ++++++------------- 2 files changed, 29 insertions(+), 24 deletions(-) create mode 100644 marietje/queues/migrations/0004_remove_playlistsong_order.py diff --git a/marietje/queues/migrations/0004_remove_playlistsong_order.py b/marietje/queues/migrations/0004_remove_playlistsong_order.py new file mode 100644 index 0000000..2033cbd --- /dev/null +++ b/marietje/queues/migrations/0004_remove_playlistsong_order.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-09-23 22:59 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('queues', '0003_queuecommand'), + ] + + operations = [ + migrations.RemoveField( + model_name='playlistsong', + name='order', + ), + ] diff --git a/marietje/queues/models.py b/marietje/queues/models.py index 2d3c18a..f5a0a0e 100644 --- a/marietje/queues/models.py +++ b/marietje/queues/models.py @@ -36,22 +36,20 @@ class PlaylistSong(models.Model): # 3: Cancelled. state = models.IntegerField(default=0) - order = models.IntegerField() - def move_up(self): - other_song = PlaylistSong.objects.filter(playlist=self.playlist, order__lt=self.order)\ - .order_by('-order').first() + other_song = PlaylistSong.objects.filter(playlist=self.playlist, id__lt=self.id)\ + .order_by('-id').first() self.switch_order(other_song) def move_down(self): - other_song = PlaylistSong.objects.filter(playlist=self.playlist, order__gt=self.order).order_by('order').first() + other_song = PlaylistSong.objects.filter(playlist=self.playlist, id__gt=self.id).order_by('id').first() self.switch_order(other_song) def switch_order(self, other_song): - old_order = self.order - self.order = other_song.order + old_id = self.id + self.id = other_song.id + other_song.id = old_id self.save() - other_song.order = old_order other_song.save() def __str__(self): @@ -91,7 +89,7 @@ class Queue(models.Model): self.songs = PlaylistSong.objects\ .filter(Q(playlist=self.playlist_id) | Q(playlist_id=self.random_playlist_id), Q(state=0) | Q(state=1))\ - .order_by('-state', 'playlist_id', 'order')\ + .order_by('-state', 'playlist_id', 'id')\ .select_related('song', 'user') return self.songs @@ -112,12 +110,10 @@ class Queue(models.Model): return songs[1:] def request(self, song, user): - playlist_songs = PlaylistSong.objects.filter(playlist=self.playlist, state=0).order_by('order') + playlist_songs = PlaylistSong.objects.filter(playlist=self.playlist, state=0).order_by('id') - order = 0 seconds_in_a_row = 0 for playlist_song in playlist_songs: - order = playlist_song.order if playlist_song.user != user: seconds_in_a_row = 0 else: @@ -129,27 +125,17 @@ class Queue(models.Model): and not user.is_superuser and settings.LIMIT_HOURS[0] <= now.hour < settings.LIMIT_HOURS[1]: return False - if order is None: - order = 0 - order += 1 - playlist_song = PlaylistSong(playlist=self.playlist, song=song, user=user, order=order) + playlist_song = PlaylistSong(playlist=self.playlist, song=song, user=user) playlist_song.save() return True def fill_random_queue(self): song_count = PlaylistSong.objects.filter(playlist_id=self.random_playlist_id, state=0).count() while song_count < 5: - order = PlaylistSong.objects.filter(playlist_id=self.random_playlist_id)\ - .aggregate(Max('order'))['order__max'] - if order is None: - order = 0 - order += 1 song = Song.objects.filter(deleted=False).order_by('?').first() if song is None: return - playlist_song = PlaylistSong(playlist=self.random_playlist, - song=song, - user=None, order=order) + playlist_song = PlaylistSong(playlist=self.random_playlist, song=song, user=None) playlist_song.save() song_count += 1