Clear unplayed queues during restarts.

This commit is contained in:
Buster "Silver Eagle" Neece 2022-03-15 03:38:32 -05:00
parent e95915f82c
commit 8055056d1d
No known key found for this signature in database
GPG Key ID: 9FC8B9E008872109
8 changed files with 110 additions and 24 deletions

View File

@ -18,6 +18,7 @@ return function (App\Event\BuildConsoleCommands $event) {
'azuracast:queue:clear' => Command\MessageQueue\ClearCommand::class,
'azuracast:settings:list' => Command\Settings\ListCommand::class,
'azuracast:settings:set' => Command\Settings\SetCommand::class,
'azuracast:station-queues:clear' => Command\ClearQueuesCommand::class,
'azuracast:account:list' => Command\Users\ListCommand::class,
'azuracast:account:login-token' => Command\Users\LoginTokenCommand::class,
'azuracast:account:reset-password' => Command\Users\ResetPasswordCommand::class,

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace App\Console\Command;
use App\Entity\Repository\StationQueueRepository;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
#[AsCommand(
name: 'azuracast:station-queues:clear',
description: 'Clear all unplayed station queues.'
)]
class ClearQueuesCommand extends CommandAbstract
{
public function __construct(
protected StationQueueRepository $queueRepo,
) {
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
// Clear all station queues.
$this->queueRepo->clearUnplayed();
$io->success('Unplayed station queues cleared.');
return 0;
}
}

View File

@ -5,11 +5,13 @@ declare(strict_types=1);
namespace App\Console\Command;
use App\Entity;
use App\Environment;
use App\Radio\Configuration;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
@ -20,6 +22,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class RestartRadioCommand extends CommandAbstract
{
public function __construct(
protected Environment $environment,
protected EntityManagerInterface $em,
protected Entity\Repository\StationRepository $stationRepo,
protected Configuration $configuration,
@ -29,7 +32,14 @@ class RestartRadioCommand extends CommandAbstract
protected function configure(): void
{
$this->addArgument('station-name', InputArgument::OPTIONAL);
$this->addArgument('station-name', InputArgument::OPTIONAL)
->addOption(
'no-supervisor-restart',
'',
InputOption::VALUE_NONE,
'Do not reload Supervisord immediately with changes.',
false
);
}
protected function execute(InputInterface $input, OutputInterface $output): int
@ -37,6 +47,7 @@ class RestartRadioCommand extends CommandAbstract
$io = new SymfonyStyle($input, $output);
$stationName = $input->getArgument('station-name');
$noSupervisorRestart = (bool)$input->getOption('no-supervisor-restart');
if (!empty($stationName)) {
$station = $this->stationRepo->findByIdentifier($stationName);
@ -57,7 +68,11 @@ class RestartRadioCommand extends CommandAbstract
$io->progressStart(count($stations));
foreach ($stations as $station) {
$this->configuration->writeConfiguration($station, true);
$this->configuration->writeConfiguration(
station: $station,
reloadSupervisor: $noSupervisorRestart,
forceRestart: true
);
$io->progressAdvance();
}

View File

@ -56,7 +56,14 @@ class SetupCommand extends CommandAbstract
$io->newLine();
$io->section(__('Refreshing All Stations'));
$this->runCommand($output, 'azuracast:radio:restart');
$this->runCommand($output, 'azuracast:station-queues:clear');
$this->runCommand(
$output,
$this->environment->isDockerStandalone()
? 'azuracast:radio:restart --no-supervisor-restart'
: 'azuracast:radio:restart'
);
// Update system setting logging when updates were last run.
$settings = $this->settingsRepo->readSettings();

View File

@ -320,7 +320,10 @@ class StationsController extends AbstractAdminApiCrudController
}
if ($adapter_changed || !$station->getIsEnabled()) {
$this->configuration->writeConfiguration($station, true);
$this->configuration->writeConfiguration(
station: $station,
forceRestart: true
);
}
return $station;

View File

@ -130,7 +130,10 @@ class ServicesController
{
// Reloading attempts to update configuration without restarting broadcasting, if possible and supported.
$station = $request->getStation();
$this->configuration->writeConfiguration($station, true, true);
$this->configuration->writeConfiguration(
station: $station,
forceRestart: true
);
return $response->withJson(new Entity\Api\Status(true, __('Station reloaded.')));
}
@ -139,7 +142,10 @@ class ServicesController
{
// Restarting will always shut down and restart any services.
$station = $request->getStation();
$this->configuration->writeConfiguration($station, true, false);
$this->configuration->writeConfiguration(
station: $station,
forceRestart: true
);
return $response->withJson(new Entity\Api\Status(true, __('Station restarted.')));
}

View File

@ -198,6 +198,16 @@ class StationQueueRepository extends Repository
->setParameter('station', $station);
}
public function clearUnplayed(): void
{
$this->em->createQuery(
<<<DQL
DELETE FROM App\Entity\StationQueue sq
WHERE sq.is_played = 0
DQL
)->execute();
}
public function cleanup(int $daysToKeep): void
{
$threshold = CarbonImmutable::now()

View File

@ -78,6 +78,7 @@ class Configuration
*/
public function writeConfiguration(
Station $station,
bool $reloadSupervisor = true,
bool $forceRestart = false,
bool $attemptReload = true
): void {
@ -93,7 +94,10 @@ class Configuration
if (!$station->getIsEnabled()) {
@unlink($supervisorConfigFile);
$this->stopForStation($station);
if ($reloadSupervisor) {
$this->stopForStation($station);
}
return;
}
@ -103,7 +107,10 @@ class Configuration
// If no processes need to be managed, remove any existing config.
if (!$frontend->hasCommand($station) && !$backend->hasCommand($station)) {
@unlink($supervisorConfigFile);
$this->stopForStation($station);
if ($reloadSupervisor) {
$this->stopForStation($station);
}
return;
}
@ -146,26 +153,28 @@ class Configuration
$backend->write($station);
// Reload Supervisord and process groups
$affected_groups = $this->reloadSupervisor();
$was_restarted = in_array($backend_group, $affected_groups, true);
if ($reloadSupervisor) {
$affected_groups = $this->reloadSupervisor();
$was_restarted = in_array($backend_group, $affected_groups, true);
if (!$was_restarted && $forceRestart) {
try {
if ($attemptReload && ($backend->supportsReload() || $frontend->supportsReload())) {
$backend->reload($station);
$frontend->reload($station);
} else {
$this->supervisor->stopProcessGroup($backend_group, true);
$this->supervisor->startProcessGroup($backend_group, true);
if (!$was_restarted && $forceRestart) {
try {
if ($attemptReload && ($backend->supportsReload() || $frontend->supportsReload())) {
$backend->reload($station);
$frontend->reload($station);
} else {
$this->supervisor->stopProcessGroup($backend_group, true);
$this->supervisor->startProcessGroup($backend_group, true);
}
} catch (SupervisorException) {
}
} catch (SupervisorException) {
$was_restarted = true;
}
$was_restarted = true;
}
if ($was_restarted) {
$this->markAsStarted($station);
if ($was_restarted) {
$this->markAsStarted($station);
}
}
}