Primo Committ

This commit is contained in:
paoloar77
2024-05-07 12:17:25 +02:00
commit e73d0e5113
7204 changed files with 884387 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Composer;
use Illuminate\Support\Str;
class FailedTableCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:failed-table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the failed queue jobs database table';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* @var \Illuminate\Support\Composer
*/
protected $composer;
/**
* Create a new failed queue jobs table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Support\Composer $composer
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
$this->files = $files;
$this->composer = $composer;
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$table = $this->laravel['config']['queue.failed.table'];
$this->replaceMigration(
$this->createBaseMigration($table), $table, Str::studly($table)
);
$this->info('Migration created successfully!');
$this->composer->dumpAutoloads();
}
/**
* Create a base migration file for the table.
*
* @param string $table
* @return string
*/
protected function createBaseMigration($table = 'failed_jobs')
{
return $this->laravel['migration.creator']->create(
'create_'.$table.'_table', $this->laravel->databasePath().'/migrations'
);
}
/**
* Replace the generated migration with the failed job table stub.
*
* @param string $path
* @param string $table
* @param string $tableClassName
* @return void
*/
protected function replaceMigration($path, $table, $tableClassName)
{
$stub = str_replace(
['{{table}}', '{{tableClassName}}'],
[$table, $tableClassName],
$this->files->get(__DIR__.'/stubs/failed_jobs.stub')
);
$this->files->put($path, $stub);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
class FlushFailedCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:flush';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Flush all of the failed queue jobs';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$this->laravel['queue.failer']->flush();
$this->info('All failed jobs deleted successfully!');
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
class ForgetFailedCommand extends Command
{
/**
* The console command signature.
*
* @var string
*/
protected $signature = 'queue:forget {id : The ID of the failed job}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Delete a failed queue job';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
if ($this->laravel['queue.failer']->forget($this->argument('id'))) {
$this->info('Failed job deleted successfully!');
} else {
$this->error('No failed job matches the given ID.');
}
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
class ListFailedCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:failed';
/**
* The console command description.
*
* @var string
*/
protected $description = 'List all of the failed queue jobs';
/**
* The table headers for the command.
*
* @var array
*/
protected $headers = ['ID', 'Connection', 'Queue', 'Class', 'Failed At'];
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
if (count($jobs = $this->getFailedJobs()) === 0) {
return $this->info('No failed jobs!');
}
$this->displayFailedJobs($jobs);
}
/**
* Compile the failed jobs into a displayable format.
*
* @return array
*/
protected function getFailedJobs()
{
$failed = $this->laravel['queue.failer']->all();
return collect($failed)->map(function ($failed) {
return $this->parseFailedJob((array) $failed);
})->filter()->all();
}
/**
* Parse the failed job row.
*
* @param array $failed
* @return array
*/
protected function parseFailedJob(array $failed)
{
$row = array_values(Arr::except($failed, ['payload', 'exception']));
array_splice($row, 3, 0, $this->extractJobName($failed['payload']));
return $row;
}
/**
* Extract the failed job name from payload.
*
* @param string $payload
* @return string|null
*/
private function extractJobName($payload)
{
$payload = json_decode($payload, true);
if ($payload && (! isset($payload['data']['command']))) {
return $payload['job'] ?? null;
} elseif ($payload && isset($payload['data']['command'])) {
return $this->matchJobName($payload);
}
}
/**
* Match the job name from the payload.
*
* @param array $payload
* @return string|null
*/
protected function matchJobName($payload)
{
preg_match('/"([^"]+)"/', $payload['data']['command'], $matches);
return $matches[1] ?? $payload['job'] ?? null;
}
/**
* Display the failed jobs in the console.
*
* @param array $jobs
* @return void
*/
protected function displayFailedJobs(array $jobs)
{
$this->table($this->headers, $jobs);
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Illuminate\Queue\Listener;
use Illuminate\Queue\ListenerOptions;
class ListenCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $signature = 'queue:listen
{connection? : The name of connection}
{--delay=0 : The number of seconds to delay failed jobs}
{--force : Force the worker to run even in maintenance mode}
{--memory=128 : The memory limit in megabytes}
{--queue= : The queue to listen on}
{--sleep=3 : Number of seconds to sleep when no job is available}
{--timeout=60 : The number of seconds a child process can run}
{--tries=1 : Number of times to attempt a job before logging it failed}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Listen to a given queue';
/**
* The queue listener instance.
*
* @var \Illuminate\Queue\Listener
*/
protected $listener;
/**
* Create a new queue listen command.
*
* @param \Illuminate\Queue\Listener $listener
* @return void
*/
public function __construct(Listener $listener)
{
parent::__construct();
$this->setOutputHandler($this->listener = $listener);
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
// We need to get the right queue for the connection which is set in the queue
// configuration file for the application. We will pull it based on the set
// connection being run for the queue operation currently being executed.
$queue = $this->getQueue(
$connection = $this->input->getArgument('connection')
);
$this->listener->listen(
$connection, $queue, $this->gatherOptions()
);
}
/**
* Get the name of the queue connection to listen on.
*
* @param string $connection
* @return string
*/
protected function getQueue($connection)
{
$connection = $connection ?: $this->laravel['config']['queue.default'];
return $this->input->getOption('queue') ?: $this->laravel['config']->get(
"queue.connections.{$connection}.queue", 'default'
);
}
/**
* Get the listener options for the command.
*
* @return \Illuminate\Queue\ListenerOptions
*/
protected function gatherOptions()
{
return new ListenerOptions(
$this->option('env'), $this->option('delay'),
$this->option('memory'), $this->option('timeout'),
$this->option('sleep'), $this->option('tries'),
$this->option('force')
);
}
/**
* Set the options on the queue listener.
*
* @param \Illuminate\Queue\Listener $listener
* @return void
*/
protected function setOutputHandler(Listener $listener)
{
$listener->setOutputHandler(function ($type, $line) {
$this->output->write($line);
});
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Illuminate\Contracts\Cache\Repository as Cache;
use Illuminate\Support\InteractsWithTime;
class RestartCommand extends Command
{
use InteractsWithTime;
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:restart';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Restart queue worker daemons after their current job';
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* Create a new queue restart command.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function __construct(Cache $cache)
{
parent::__construct();
$this->cache = $cache;
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$this->cache->forever('illuminate:queue:restart', $this->currentTime());
$this->info('Broadcasting queue restart signal.');
}
}

View File

@@ -0,0 +1,118 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
class RetryCommand extends Command
{
/**
* The console command signature.
*
* @var string
*/
protected $signature = 'queue:retry
{id?* : The ID of the failed job or "all" to retry all jobs}
{--range=* : Range of job IDs (numeric) to be retried}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Retry a failed queue job';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
foreach ($this->getJobIds() as $id) {
$job = $this->laravel['queue.failer']->find($id);
if (is_null($job)) {
$this->error("Unable to find failed job with ID [{$id}].");
} else {
$this->retryJob($job);
$this->info("The failed job [{$id}] has been pushed back onto the queue!");
$this->laravel['queue.failer']->forget($id);
}
}
}
/**
* Get the job IDs to be retried.
*
* @return array
*/
protected function getJobIds()
{
$ids = (array) $this->argument('id');
if (count($ids) === 1 && $ids[0] === 'all') {
return Arr::pluck($this->laravel['queue.failer']->all(), 'id');
}
if ($ranges = (array) $this->option('range')) {
$ids = array_merge($ids, $this->getJobIdsByRanges($ranges));
}
return array_values(array_filter(array_unique($ids)));
}
/**
* Get the job IDs ranges, if applicable.
*
* @param array $ranges
* @return array
*/
protected function getJobIdsByRanges(array $ranges)
{
$ids = [];
foreach ($ranges as $range) {
if (preg_match('/^[0-9]+\-[0-9]+$/', $range)) {
$ids = array_merge($ids, range(...explode('-', $range)));
}
}
return $ids;
}
/**
* Retry the queue job.
*
* @param \stdClass $job
* @return void
*/
protected function retryJob($job)
{
$this->laravel['queue']->connection($job->connection)->pushRaw(
$this->resetAttempts($job->payload), $job->queue
);
}
/**
* Reset the payload attempts.
*
* Applicable to Redis jobs which store attempts in their payload.
*
* @param string $payload
* @return string
*/
protected function resetAttempts($payload)
{
$payload = json_decode($payload, true);
if (isset($payload['attempts'])) {
$payload['attempts'] = 0;
}
return json_encode($payload);
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Composer;
use Illuminate\Support\Str;
class TableCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the queue jobs database table';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* @var \Illuminate\Support\Composer
*/
protected $composer;
/**
* Create a new queue job table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Support\Composer $composer
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
$this->files = $files;
$this->composer = $composer;
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$table = $this->laravel['config']['queue.connections.database.table'];
$this->replaceMigration(
$this->createBaseMigration($table), $table, Str::studly($table)
);
$this->info('Migration created successfully!');
$this->composer->dumpAutoloads();
}
/**
* Create a base migration file for the table.
*
* @param string $table
* @return string
*/
protected function createBaseMigration($table = 'jobs')
{
return $this->laravel['migration.creator']->create(
'create_'.$table.'_table', $this->laravel->databasePath().'/migrations'
);
}
/**
* Replace the generated migration with the job table stub.
*
* @param string $path
* @param string $table
* @param string $tableClassName
* @return void
*/
protected function replaceMigration($path, $table, $tableClassName)
{
$stub = str_replace(
['{{table}}', '{{tableClassName}}'],
[$table, $tableClassName],
$this->files->get(__DIR__.'/stubs/jobs.stub')
);
$this->files->put($path, $stub);
}
}

View File

@@ -0,0 +1,226 @@
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Illuminate\Contracts\Cache\Repository as Cache;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Queue\Worker;
use Illuminate\Queue\WorkerOptions;
use Illuminate\Support\Carbon;
class WorkCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $signature = 'queue:work
{connection? : The name of the queue connection to work}
{--queue= : The names of the queues to work}
{--daemon : Run the worker in daemon mode (Deprecated)}
{--once : Only process the next job on the queue}
{--stop-when-empty : Stop when the queue is empty}
{--delay=0 : The number of seconds to delay failed jobs}
{--force : Force the worker to run even in maintenance mode}
{--memory=128 : The memory limit in megabytes}
{--sleep=3 : Number of seconds to sleep when no job is available}
{--timeout=60 : The number of seconds a child process can run}
{--tries=1 : Number of times to attempt a job before logging it failed}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Start processing jobs on the queue as a daemon';
/**
* The queue worker instance.
*
* @var \Illuminate\Queue\Worker
*/
protected $worker;
/**
* The cache store implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* Create a new queue work command.
*
* @param \Illuminate\Queue\Worker $worker
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function __construct(Worker $worker, Cache $cache)
{
parent::__construct();
$this->cache = $cache;
$this->worker = $worker;
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
if ($this->downForMaintenance() && $this->option('once')) {
return $this->worker->sleep($this->option('sleep'));
}
// We'll listen to the processed and failed events so we can write information
// to the console as jobs are processed, which will let the developer watch
// which jobs are coming through a queue and be informed on its progress.
$this->listenForEvents();
$connection = $this->argument('connection')
?: $this->laravel['config']['queue.default'];
// We need to get the right queue for the connection which is set in the queue
// configuration file for the application. We will pull it based on the set
// connection being run for the queue operation currently being executed.
$queue = $this->getQueue($connection);
$this->runWorker(
$connection, $queue
);
}
/**
* Run the worker instance.
*
* @param string $connection
* @param string $queue
* @return array
*/
protected function runWorker($connection, $queue)
{
$this->worker->setCache($this->cache);
return $this->worker->{$this->option('once') ? 'runNextJob' : 'daemon'}(
$connection, $queue, $this->gatherWorkerOptions()
);
}
/**
* Gather all of the queue worker options as a single object.
*
* @return \Illuminate\Queue\WorkerOptions
*/
protected function gatherWorkerOptions()
{
return new WorkerOptions(
$this->option('delay'), $this->option('memory'),
$this->option('timeout'), $this->option('sleep'),
$this->option('tries'), $this->option('force'),
$this->option('stop-when-empty')
);
}
/**
* Listen for the queue events in order to update the console output.
*
* @return void
*/
protected function listenForEvents()
{
$this->laravel['events']->listen(JobProcessing::class, function ($event) {
$this->writeOutput($event->job, 'starting');
});
$this->laravel['events']->listen(JobProcessed::class, function ($event) {
$this->writeOutput($event->job, 'success');
});
$this->laravel['events']->listen(JobFailed::class, function ($event) {
$this->writeOutput($event->job, 'failed');
$this->logFailedJob($event);
});
}
/**
* Write the status output for the queue worker.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param string $status
* @return void
*/
protected function writeOutput(Job $job, $status)
{
switch ($status) {
case 'starting':
return $this->writeStatus($job, 'Processing', 'comment');
case 'success':
return $this->writeStatus($job, 'Processed', 'info');
case 'failed':
return $this->writeStatus($job, 'Failed', 'error');
}
}
/**
* Format the status output for the queue worker.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param string $status
* @param string $type
* @return void
*/
protected function writeStatus(Job $job, $status, $type)
{
$this->output->writeln(sprintf(
"<{$type}>[%s][%s] %s</{$type}> %s",
Carbon::now()->format('Y-m-d H:i:s'),
$job->getJobId(),
str_pad("{$status}:", 11), $job->resolveName()
));
}
/**
* Store a failed job event.
*
* @param \Illuminate\Queue\Events\JobFailed $event
* @return void
*/
protected function logFailedJob(JobFailed $event)
{
$this->laravel['queue.failer']->log(
$event->connectionName, $event->job->getQueue(),
$event->job->getRawBody(), $event->exception
);
}
/**
* Get the queue name for the worker.
*
* @param string $connection
* @return string
*/
protected function getQueue($connection)
{
return $this->option('queue') ?: $this->laravel['config']->get(
"queue.connections.{$connection}.queue", 'default'
);
}
/**
* Determine if the worker should run in maintenance mode.
*
* @return bool
*/
protected function downForMaintenance()
{
return $this->option('force') ? false : $this->laravel->isDownForMaintenance();
}
}

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Create{{tableClassName}}Table extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('{{table}}', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('{{table}}');
}
}

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Create{{tableClassName}}Table extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('{{table}}', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue')->index();
$table->longText('payload');
$table->unsignedTinyInteger('attempts');
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('{{table}}');
}
}