-
Notifications
You must be signed in to change notification settings - Fork 11.7k
Feature/queue pause resume #57800
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/queue pause resume #57800
Changes from 3 commits
e45a8a6
0458552
14cb6bf
26f15a5
3133f07
10e06f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| <?php | ||
|
|
||
| namespace Illuminate\Queue\Console; | ||
|
|
||
| use Illuminate\Console\Command; | ||
| use Illuminate\Contracts\Queue\Factory as QueueManager; | ||
| use Symfony\Component\Console\Attribute\AsCommand; | ||
|
|
||
| #[AsCommand(name: 'queue:pause')] | ||
| class PauseCommand extends Command | ||
| { | ||
| /** | ||
| * The console command name. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $signature = 'queue:pause {queue : The name of the queue to pause} | ||
| {--ttl=86400 : The TTL for the pause in seconds}'; | ||
|
|
||
| /** | ||
| * The console command description. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $description = 'Pause processing for a specific queue'; | ||
|
|
||
| /** | ||
| * The queue manager instance. | ||
| * | ||
| * @var \Illuminate\Contracts\Queue\Factory | ||
| */ | ||
| protected $manager; | ||
|
|
||
| /** | ||
| * Create a new queue pause command. | ||
| * | ||
| * @param \Illuminate\Contracts\Queue\Factory $manager | ||
| */ | ||
| public function __construct(QueueManager $manager) | ||
| { | ||
| parent::__construct(); | ||
|
|
||
| $this->manager = $manager; | ||
| } | ||
|
|
||
| /** | ||
| * Execute the console command. | ||
| * | ||
| * @return int | ||
| */ | ||
| public function handle() | ||
| { | ||
| $queue = $this->argument('queue'); | ||
| $ttl = (int) $this->option('ttl'); | ||
|
|
||
| $this->manager->pause($queue, $ttl); | ||
|
|
||
| $this->components->info("Queue [{$queue}] has been paused."); | ||
|
|
||
| return 0; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| <?php | ||
|
|
||
| namespace Illuminate\Queue\Console; | ||
|
|
||
| use Illuminate\Console\Command; | ||
| use Illuminate\Contracts\Queue\Factory as QueueManager; | ||
| use Symfony\Component\Console\Attribute\AsCommand; | ||
|
|
||
| #[AsCommand(name: 'queue:pause:list')] | ||
| class PauseListCommand extends Command | ||
| { | ||
| /** | ||
| * The console command name. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $name = 'queue:pause:list'; | ||
|
|
||
| /** | ||
| * The console command description. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $description = 'List all currently paused queues'; | ||
|
|
||
| /** | ||
| * The queue manager instance. | ||
| * | ||
| * @var \Illuminate\Contracts\Queue\Factory | ||
| */ | ||
| protected $manager; | ||
|
|
||
| /** | ||
| * Create a new queue pause list command. | ||
| * | ||
| * @param \Illuminate\Contracts\Queue\Factory $manager | ||
| */ | ||
| public function __construct(QueueManager $manager) | ||
| { | ||
| parent::__construct(); | ||
|
|
||
| $this->manager = $manager; | ||
| } | ||
|
|
||
| /** | ||
| * Execute the console command. | ||
| * | ||
| * @return int | ||
| */ | ||
| public function handle() | ||
| { | ||
| $pausedQueues = $this->manager->getPausedQueues(); | ||
|
|
||
| if (empty($pausedQueues)) { | ||
| $this->components->info('No queues are currently paused.'); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| $this->components->info('Paused Queues:'); | ||
|
|
||
| $this->table( | ||
| ['Queue Name'], | ||
| collect($pausedQueues)->map(fn ($queue) => [$queue])->toArray() | ||
| ); | ||
|
|
||
| return 0; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| <?php | ||
|
|
||
| namespace Illuminate\Queue\Console; | ||
|
|
||
| use Illuminate\Console\Command; | ||
| use Illuminate\Contracts\Queue\Factory as QueueManager; | ||
| use Symfony\Component\Console\Attribute\AsCommand; | ||
|
|
||
| #[AsCommand(name: 'queue:resume')] | ||
| class ResumeCommand extends Command | ||
| { | ||
| /** | ||
| * The console command name. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $signature = 'queue:resume {queue : The name of the queue to resume}'; | ||
|
|
||
| /** | ||
| * The console command description. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $description = 'Resume processing for a paused queue'; | ||
|
|
||
| /** | ||
| * The queue manager instance. | ||
| * | ||
| * @var \Illuminate\Contracts\Queue\Factory | ||
| */ | ||
| protected $manager; | ||
|
|
||
| /** | ||
| * Create a new queue resume command. | ||
| * | ||
| * @param \Illuminate\Contracts\Queue\Factory $manager | ||
| */ | ||
| public function __construct(QueueManager $manager) | ||
| { | ||
| parent::__construct(); | ||
|
|
||
| $this->manager = $manager; | ||
| } | ||
|
|
||
| /** | ||
| * Execute the console command. | ||
| * | ||
| * @return int | ||
| */ | ||
| public function handle() | ||
| { | ||
| $queue = $this->argument('queue'); | ||
|
|
||
| if (! $this->manager->isPaused($queue)) { | ||
| $this->components->warn("Queue [{$queue}] is not paused."); | ||
|
|
||
| return 1; | ||
| } | ||
|
|
||
| $this->manager->resume($queue); | ||
|
|
||
| $this->components->info("Queue [{$queue}] has been resumed."); | ||
|
|
||
| return 0; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -295,6 +295,88 @@ public function setApplication($app) | |
| return $this; | ||
| } | ||
|
|
||
| /** | ||
| * Pause a queue by name. | ||
| * | ||
| * @param string $queue | ||
| * @param int $ttl | ||
| * @return void | ||
| */ | ||
| public function pause($queue, $ttl = 86400) | ||
| { | ||
| $cache = $this->app['cache']->store(); | ||
|
|
||
| $cache->put("queue_paused:{$queue}", true, $ttl); | ||
|
||
|
|
||
| // Add to the list of paused queues | ||
| $pausedQueues = $this->getPausedQueues(); | ||
|
|
||
| if (! in_array($queue, $pausedQueues)) { | ||
| $pausedQueues[] = $queue; | ||
| $this->storePausedQueuesList($pausedQueues); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Resume a paused queue by name. | ||
| * | ||
| * @param string $queue | ||
| * @return void | ||
| */ | ||
| public function resume($queue) | ||
| { | ||
| $cache = $this->app['cache']->store(); | ||
|
|
||
| $cache->forget("queue_paused:{$queue}"); | ||
|
|
||
| // Remove from the list of paused queues | ||
| $pausedQueues = $this->getPausedQueues(); | ||
|
|
||
| if (($key = array_search($queue, $pausedQueues)) !== false) { | ||
| unset($pausedQueues[$key]); | ||
| $this->storePausedQueuesList(array_values($pausedQueues)); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Determine if a queue is paused. | ||
| * | ||
| * @param string $queue | ||
| * @return bool | ||
| */ | ||
| public function isPaused($queue) | ||
| { | ||
| $cache = $this->app['cache']->store(); | ||
|
|
||
| return (bool) $cache->get("queue_paused:{$queue}", false); | ||
| } | ||
|
|
||
| /** | ||
| * Get all paused queues. | ||
| * | ||
| * @return array | ||
| */ | ||
| public function getPausedQueues() | ||
| { | ||
| $cache = $this->app['cache']->store(); | ||
|
|
||
| // This implementation stores a list of paused queues | ||
| return $cache->get('queue_paused_list', []); | ||
| } | ||
|
|
||
| /** | ||
| * Store the list of paused queues. | ||
| * | ||
| * @param array $queues | ||
| * @return void | ||
| */ | ||
| protected function storePausedQueuesList($queues) | ||
| { | ||
| $cache = $this->app['cache']->store(); | ||
|
|
||
| $cache->forever('queue_paused_list', $queues); | ||
| } | ||
|
|
||
| /** | ||
| * Dynamically pass calls to the default connection. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -372,6 +372,11 @@ protected function getNextJob($connection, $queue) | |
| } | ||
|
|
||
| foreach (explode(',', $queue) as $index => $queue) { | ||
| // Skip paused queues | ||
| if ($this->isQueuePaused($queue)) { | ||
|
||
| continue; | ||
| } | ||
|
|
||
| if (! is_null($job = $popJobCallback($queue, $index))) { | ||
| $this->raiseAfterJobPopEvent($connection->getConnectionName(), $job); | ||
|
|
||
|
|
@@ -387,6 +392,21 @@ protected function getNextJob($connection, $queue) | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Determine if a queue is paused. | ||
| * | ||
| * @param string $queue | ||
| * @return bool | ||
| */ | ||
| protected function isQueuePaused($queue) | ||
| { | ||
| if (! $this->cache) { | ||
| return false; | ||
| } | ||
|
|
||
| return (bool) $this->cache->get("queue_paused:{$queue}", false); | ||
| } | ||
|
|
||
| /** | ||
| * Process the given job. | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very strange solution to pause just for one day. Why not week, year, or 30 seconds? It's better to pass null as default, meaning by default pausing queue until it's resumed manualy.
For other cases developers still will have a way to pass any ttl they want in certain case