Further optimize the AutoDJ queue builder.
This commit is contained in:
parent
e7cf4e585e
commit
9e0cddbb39
|
@ -29,6 +29,11 @@ release channel, you can take advantage of these new features and fixes.
|
|||
- Instances of the "Pause" icon across the system have been replaced with the "Stop" icon to more properly indicate what
|
||||
they do.
|
||||
|
||||
- Heavy performance optimizations have been made in the following areas:
|
||||
- Looping through, and processing, station media (5-minute sync)
|
||||
- Processing listeners for stations with large listener counts
|
||||
- The AutoDJ queue building process
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Fixed a minor bug with the `is_now` parameter on the Schedule API endpoint.
|
||||
|
|
|
@ -101,36 +101,6 @@ class StationQueueRepository extends Repository
|
|||
return $this->getUpcomingBaseQuery($station)->getQuery();
|
||||
}
|
||||
|
||||
public function clearDuplicatesInQueue(Entity\Station $station): void
|
||||
{
|
||||
$upcomingQueue = $this->em->createQuery(
|
||||
<<<'DQL'
|
||||
SELECT sq.id, sq.song_id
|
||||
FROM App\Entity\StationQueue sq
|
||||
WHERE sq.station = :station
|
||||
AND sq.sent_to_autodj = 0
|
||||
ORDER BY sq.timestamp_cued ASC
|
||||
DQL
|
||||
)->setParameter('station', $station)
|
||||
->getArrayResult();
|
||||
|
||||
$removeQueueItemQuery = $this->em->createQuery(
|
||||
<<<'DQL'
|
||||
DELETE FROM App\Entity\StationQueue sq WHERE sq.id = :id
|
||||
DQL
|
||||
);
|
||||
|
||||
$lastItem = null;
|
||||
foreach ($upcomingQueue as $queue) {
|
||||
if (null !== $lastItem && $lastItem === $queue['song_id']) {
|
||||
$removeQueueItemQuery->setParameter('id', $queue['id'])->execute();
|
||||
continue;
|
||||
}
|
||||
|
||||
$lastItem = $queue['song_id'];
|
||||
}
|
||||
}
|
||||
|
||||
public function getNextInQueue(Entity\Station $station): ?Entity\StationQueue
|
||||
{
|
||||
return $this->getUpcomingBaseQuery($station)
|
||||
|
|
|
@ -142,35 +142,50 @@ class AutoDJ
|
|||
$stationTz = $station->getTimezoneObject();
|
||||
|
||||
$upcomingQueue = $this->queueRepo->getUpcomingQueue($station);
|
||||
$queueLength = count($upcomingQueue);
|
||||
|
||||
$lastSongId = null;
|
||||
$queueLength = 0;
|
||||
|
||||
foreach ($upcomingQueue as $queueRow) {
|
||||
// Prevent the exact same track from being played twice during this loop
|
||||
if (null !== $lastSongId && $lastSongId === $queueRow->getSongId()) {
|
||||
$this->em->remove($queueRow);
|
||||
continue;
|
||||
}
|
||||
|
||||
$queueLength++;
|
||||
$lastSongId = $queueRow->getSongId();
|
||||
|
||||
$queueRow->setTimestampCued($now->getTimestamp());
|
||||
$this->em->persist($queueRow);
|
||||
|
||||
$timestampCued = CarbonImmutable::createFromTimestamp($queueRow->getTimestampCued(), $stationTz);
|
||||
$duration = $queueRow->getDuration() ?? 1;
|
||||
$now = $this->getAdjustedNow($station, $timestampCued, $duration);
|
||||
$now = $this->getAdjustedNow($station, $timestampCued, $queueRow->getDuration() ?? 1);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
$this->em->clear();
|
||||
|
||||
// Build the remainder of the queue.
|
||||
while ($queueLength < $maxQueueLength) {
|
||||
$station = $this->em->refetch($station);
|
||||
$now = $this->cueNextSong($station, $now);
|
||||
$queueLength++;
|
||||
$queueRow = $this->cueNextSong($station, $now);
|
||||
if ($queueRow instanceof Entity\StationQueue) {
|
||||
$this->em->persist($queueRow);
|
||||
|
||||
// Prevent the exact same track from being played twice during this loop
|
||||
if (null !== $lastSongId && $lastSongId === $queueRow->getSongId()) {
|
||||
$this->em->remove($queueRow);
|
||||
} else {
|
||||
$lastSongId = $queueRow->getSongId();
|
||||
$now = $this->getAdjustedNow($station, $now, $queueRow->getDuration() ?? 1);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
$this->em->clear();
|
||||
gc_collect_cycles();
|
||||
$queueLength++;
|
||||
}
|
||||
|
||||
$station = $this->em->refetch($station);
|
||||
|
||||
$this->queueRepo->clearDuplicatesInQueue($station);
|
||||
|
||||
$this->logger->popProcessor();
|
||||
}
|
||||
|
||||
|
@ -204,7 +219,7 @@ class AutoDJ
|
|||
return max($now, $adjustedNow);
|
||||
}
|
||||
|
||||
protected function cueNextSong(Entity\Station $station, CarbonInterface $now): CarbonInterface
|
||||
protected function cueNextSong(Entity\Station $station, CarbonInterface $now): ?Entity\StationQueue
|
||||
{
|
||||
$this->logger->debug(
|
||||
'Adding to station queue.',
|
||||
|
@ -224,18 +239,9 @@ class AutoDJ
|
|||
|
||||
$queueRow = $event->getNextSong();
|
||||
if ($queueRow instanceof Entity\StationQueue) {
|
||||
$mediaRow = $queueRow->getMedia();
|
||||
if ($mediaRow instanceof Entity\StationMedia) {
|
||||
$mediaRow->updateSongId();
|
||||
$this->em->persist($mediaRow);
|
||||
}
|
||||
|
||||
$queueRow->setLog($testHandler->getRecords());
|
||||
$this->em->persist($queueRow);
|
||||
|
||||
$now = $this->getAdjustedNow($station, $now, $queueRow->getDuration());
|
||||
}
|
||||
|
||||
return $now;
|
||||
return $queueRow;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue