Skip to content

Commit

Permalink
[9.x] Improves queue:work command (laravel#43252)
Browse files Browse the repository at this point in the history
* Fixes `queue:work` on failures

* Checks if null first

* Ensures the last output is printed

* Ensures latest output is printed on `queue:listen`

* Improves feedback when job released

* Apply fixes from StyleCI

* Removes unused property

* Refactor

* Renames event

Co-authored-by: StyleCI Bot <[email protected]>
  • Loading branch information
nunomaduro and StyleCIBot authored Jul 18, 2022
1 parent b15dc2a commit d425952
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/Illuminate/Queue/Console/WorkCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Queue\Events\JobReleasedAfterException;
use Illuminate\Queue\Worker;
use Illuminate\Queue\WorkerOptions;
use Illuminate\Support\Carbon;
Expand Down Expand Up @@ -79,6 +80,13 @@ class WorkCommand extends Command
*/
protected $latestStartedAt;

/**
* Holds the status of the last processed job, if any.
*
* @var string|null
*/
protected $latestStatus;

/**
* Create a new queue work command.
*
Expand Down Expand Up @@ -180,6 +188,10 @@ protected function listenForEvents()
$this->writeOutput($event->job, 'success');
});

$this->laravel['events']->listen(JobReleasedAfterException::class, function ($event) {
$this->writeOutput($event->job, 'released_after_exception');
});

$this->laravel['events']->listen(JobFailed::class, function ($event) {
$this->writeOutput($event->job, 'failed');

Expand All @@ -198,17 +210,30 @@ protected function writeOutput(Job $job, $status)
{
if ($status == 'starting') {
$this->latestStartedAt = microtime(true);
$this->latestStatus = $status;

$formattedStartedAt = Carbon::now()->format('Y-m-d H:i:s');

return $this->output->write(" <fg=gray>{$formattedStartedAt}</> {$job->resolveName()}");
}

if ($this->latestStatus && $this->latestStatus != 'starting') {
$formattedStartedAt = Carbon::createFromTimestamp($this->latestStartedAt)->format('Y-m-d H:i:s');

$this->output->write(" <fg=gray>{$formattedStartedAt}</> {$job->resolveName()}");
}

$runTime = number_format((microtime(true) - $this->latestStartedAt) * 1000, 2).'ms';
$dots = max(terminal()->width() - mb_strlen($job->resolveName()) - mb_strlen($runTime) - 31, 0);

$this->output->write(' '.str_repeat('<fg=gray>.</>', $dots));
$this->output->write(" <fg=gray>$runTime</>");
$this->output->writeln($status == 'success' ? ' <fg=green;options=bold>DONE</>' : ' <fg=red;options=bold>FAIL</>');

$this->output->writeln(match ($this->latestStatus = $status) {
'success' => ' <fg=green;options=bold>DONE</>',
'released_after_exception' => ' <fg=yellow;options=bold>FAIL</>',
default => ' <fg=red;options=bold>FAIL</>',
});
}

/**
Expand Down
33 changes: 33 additions & 0 deletions src/Illuminate/Queue/Events/JobReleasedAfterException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Illuminate\Queue\Events;

class JobReleasedAfterException
{
/**
* The connection name.
*
* @var string
*/
public $connectionName;

/**
* The job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
public $job;

/**
* Create a new event instance.
*
* @param string $connectionName
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
public function __construct($connectionName, $job)
{
$this->job = $job;
$this->connectionName = $connectionName;
}
}
5 changes: 5 additions & 0 deletions src/Illuminate/Queue/Worker.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Queue\Events\JobExceptionOccurred;
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Queue\Events\JobReleasedAfterException;
use Illuminate\Queue\Events\Looping;
use Illuminate\Queue\Events\WorkerStopping;
use Illuminate\Support\Carbon;
Expand Down Expand Up @@ -469,6 +470,10 @@ protected function handleJobException($connectionName, $job, WorkerOptions $opti
// another listener (or this same one). We will re-throw this exception after.
if (! $job->isDeleted() && ! $job->isReleased() && ! $job->hasFailed()) {
$job->release($this->calculateBackoff($job, $options));

$this->events->dispatch(new JobReleasedAfterException(
$connectionName, $job
));
}
}

Expand Down

0 comments on commit d425952

Please sign in to comment.