Fix race condition when requesting songs, causing them to get the same order value.

This commit is contained in:
Jim Driessen
2017-09-24 01:02:52 +02:00
committed by Daan Sprenkels
parent 3abb39916d
commit f6492a70df
2 changed files with 29 additions and 24 deletions

View File

@ -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',
),
]

View File

@ -36,22 +36,20 @@ class PlaylistSong(models.Model):
# 3: Cancelled. # 3: Cancelled.
state = models.IntegerField(default=0) state = models.IntegerField(default=0)
order = models.IntegerField()
def move_up(self): def move_up(self):
other_song = PlaylistSong.objects.filter(playlist=self.playlist, order__lt=self.order)\ other_song = PlaylistSong.objects.filter(playlist=self.playlist, id__lt=self.id)\
.order_by('-order').first() .order_by('-id').first()
self.switch_order(other_song) self.switch_order(other_song)
def move_down(self): 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) self.switch_order(other_song)
def switch_order(self, other_song): def switch_order(self, other_song):
old_order = self.order old_id = self.id
self.order = other_song.order self.id = other_song.id
other_song.id = old_id
self.save() self.save()
other_song.order = old_order
other_song.save() other_song.save()
def __str__(self): def __str__(self):
@ -91,7 +89,7 @@ class Queue(models.Model):
self.songs = PlaylistSong.objects\ self.songs = PlaylistSong.objects\
.filter(Q(playlist=self.playlist_id) | Q(playlist_id=self.random_playlist_id), .filter(Q(playlist=self.playlist_id) | Q(playlist_id=self.random_playlist_id),
Q(state=0) | Q(state=1))\ Q(state=0) | Q(state=1))\
.order_by('-state', 'playlist_id', 'order')\ .order_by('-state', 'playlist_id', 'id')\
.select_related('song', 'user') .select_related('song', 'user')
return self.songs return self.songs
@ -112,12 +110,10 @@ class Queue(models.Model):
return songs[1:] return songs[1:]
def request(self, song, user): 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 seconds_in_a_row = 0
for playlist_song in playlist_songs: for playlist_song in playlist_songs:
order = playlist_song.order
if playlist_song.user != user: if playlist_song.user != user:
seconds_in_a_row = 0 seconds_in_a_row = 0
else: 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]: and not user.is_superuser and settings.LIMIT_HOURS[0] <= now.hour < settings.LIMIT_HOURS[1]:
return False return False
if order is None: playlist_song = PlaylistSong(playlist=self.playlist, song=song, user=user)
order = 0
order += 1
playlist_song = PlaylistSong(playlist=self.playlist, song=song, user=user, order=order)
playlist_song.save() playlist_song.save()
return True return True
def fill_random_queue(self): def fill_random_queue(self):
song_count = PlaylistSong.objects.filter(playlist_id=self.random_playlist_id, state=0).count() song_count = PlaylistSong.objects.filter(playlist_id=self.random_playlist_id, state=0).count()
while song_count < 5: 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() song = Song.objects.filter(deleted=False).order_by('?').first()
if song is None: if song is None:
return return
playlist_song = PlaylistSong(playlist=self.random_playlist, playlist_song = PlaylistSong(playlist=self.random_playlist, song=song, user=None)
song=song,
user=None, order=order)
playlist_song.save() playlist_song.save()
song_count += 1 song_count += 1