diff --git a/composer.json b/composer.json index 21bf978..1905395 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,12 @@ { "name": "barryvdh/laravel-async-queue", "description": "Async Queue Driver for Laravel (Push to background)", - "keywords": ["laravel", "queue", "async", "background"], + "keywords": [ + "laravel", + "queue", + "async", + "background" + ], "license": "MIT", "authors": [ { @@ -10,10 +15,9 @@ } ], "require": { - "php": ">=7", - "illuminate/support": "5.5.x|5.6.x|5.7.x|5.8.x", - "illuminate/console": "5.5.x|5.6.x|5.7.x|5.8.x", - "symfony/process": "^3.2|^4" + "php": "^8.2", + "illuminate/support": "^11.0|^12.0", + "illuminate/queue": "^11.0|^12.0" }, "autoload": { "psr-4": { @@ -22,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "0.7-dev" + "dev-master": "0.8-dev" }, "laravel": { "providers": [ diff --git a/readme.md b/readme.md index 4aba467..e2423e7 100644 --- a/readme.md +++ b/readme.md @@ -1,62 +1,34 @@ -# Laravel 5 Async Queue Driver +# Laravel Async Queue Driver -## Push a function/closure to the background. - - -### For Laravel 5.4, check the [0.6 branch](https://github.com/barryvdh/laravel-async-queue/tree/v0.6.0) +## Available as `background` in Laravel [v12.37](https://github.com/laravel/framework/releases/tag/v12.37.0) +Update you config to use driver 'background' and you don't need this package anymore. -### For Laravel 5.3, check the [0.5 branch](https://github.com/barryvdh/laravel-async-queue/tree/v0.5.0) +## Push a function/closure to the background. -Just like the 'sync' driver, this is not a real queue driver. It is always fired immediatly. +Just like the 'sync' or 'deferred' connection, this is not a real queue. It is always fired immediately. The only difference is that the closure is sent to the background without waiting for the response. This package is more usable as an alternative for running incidental tasks in the background, without setting up a 'real' queue driver. +It is similar to the 'deferred' connection, but it runs in a background process, so might be more suitable for long running tasks. -> **Note:** This is using the DatabaseQueue, so make sure you set that up first, including migrations. - +> Note: Since v0.8 this uses the Concurrently::defer() method instead of the database queue. No database migrations tables are required now. The config can be simplified as below. +> ### Install Require the latest version of this package with Composer composer require barryvdh/laravel-async-queue -Add the Service Provider to the providers array in config/app.php - - Barryvdh\Queue\AsyncServiceProvider::class, - -You need to create the migration table for queues and run it. - - $ php artisan queue:table - $ php artisan migrate - You should now be able to use the async driver in config/queue.php. Use the same config as for the database, but use async as driver. 'connections' => array( ... 'async' => array( 'driver' => 'async', - 'table' => 'jobs', - 'queue' => 'default', - 'expire' => 60, ), ... } Set the default to `async`, either by changing to config or setting `QUEUE_DRIVER` in your `.env` file to `async`. -> Note: By default, `php` is used as the binary path to PHP. You can change this by adding the `binary` option to the queue config. You can also add extra arguments (for HHVM for example) - - 'connections' => array( - ... - 'async' => array( - 'driver' => 'async', - 'table' => 'jobs', - 'queue' => 'default', - 'expire' => 60, - 'binary' => 'php', - 'binary_args' => '', - ), - ... - } - It should work the same as the sync driver, so no need to run a queue listener. Downside is that you cannot actually queue or plan things. Queue::later() is also fired directly. For more info see http://laravel.com/docs/queues diff --git a/src/AsyncQueue.php b/src/AsyncQueue.php index a59bfed..a30db73 100644 --- a/src/AsyncQueue.php +++ b/src/AsyncQueue.php @@ -1,187 +1,18 @@ binary = $binary; - $this->binaryArgs = $binaryArgs; - $this->connectionName = $connectionName; - } - - /** - * Push a new job onto the queue. - * - * @param string $job - * @param mixed $data - * @param string|null $queue - * - * @return int + * {@inheritdoc} */ public function push($job, $data = '', $queue = null) { - $id = parent::push($job, $data, $queue); - $this->startProcess($id); - - return $id; - } - - /** - * Push a raw payload onto the queue. - * - * @param string $payload - * @param string $queue - * @param array $options - * @return mixed - */ - public function pushRaw($payload, $queue = null, array $options = []) - { - $id = parent::pushRaw($payload, $queue, $options); - $this->startProcess($id); - - return $id; - } - - /** - * Push a new job onto the queue after a delay. - * - * @param \DateTime|int $delay - * @param string $job - * @param mixed $data - * @param string|null $queue - * - * @return int - */ - public function later($delay, $job, $data = '', $queue = null) - { - $id = parent::later($delay, $job, $data, $queue); - $this->startProcess($id); - - return $id; - } - - /** - * Create an array to insert for the given job. - * - * @param string|null $queue - * @param string $payload - * @param int $availableAt - * @param int $attempts - * @return array - */ - protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0) - { - $record = parent::buildDatabaseRecord($queue, $payload, $availableAt, $attempts); - $record['reserved_at'] = $this->currentTime(); - - return $record; - } - - /** - * Get the next available job for the queue. - * - * @param int $id - * @return DatabaseJob - */ - public function getJobFromId($id) - { - $job = $this->database->table($this->table) - ->where('id', $id) - ->first(); - - if ($job) { - $job = $this->markJobAsReserved(new DatabaseJobRecord((object) $job)); - return new DatabaseJob( - $this->container, $this, $job, $this->connectionName, $job->queue - ); - } - } - - /** - * Make a Process for the Artisan command for the job id. - * - * @param int $id - * - * @return void - */ - public function startProcess($id) - { - $command = $this->getCommand($id); - $cwd = base_path(); - - $process = new Process($command, $cwd); - $process->run(); - } - - /** - * Get the Artisan command as a string for the job id. - * - * @param int $id - * - * @return string - */ - protected function getCommand($id) - { - $connection = $this->connectionName; - $cmd = '%s artisan queue:async %d %s'; - $cmd = $this->getBackgroundCommand($cmd); - - $binary = $this->getPhpBinary(); - - return sprintf($cmd, $binary, $id, $connection); - } - - /** - * Get the escaped PHP Binary from the configuration - * - * @return string - */ - protected function getPhpBinary() - { - $path = $this->binary; - if ( ! defined('PHP_WINDOWS_VERSION_BUILD')) { - $path = escapeshellarg($path); - } - - $args = $this->binaryArgs; - if (is_array($args)) { - $args = implode(' ', $args); - } - - return trim($path . ' ' . $args); - } - - protected function getBackgroundCommand($cmd) - { - if (defined('PHP_WINDOWS_VERSION_BUILD')) { - return 'start /B ' . $cmd . ' > NUL'; - } - - return $cmd . ' > /dev/null 2>&1 &'; + Concurrency::driver('process') + ->defer(fn () => Queue::connection('sync')->push($job, $data, $queue)); } } diff --git a/src/AsyncServiceProvider.php b/src/AsyncServiceProvider.php index fab4b14..2989964 100644 --- a/src/AsyncServiceProvider.php +++ b/src/AsyncServiceProvider.php @@ -3,74 +3,32 @@ namespace Barryvdh\Queue; use Barryvdh\Queue\Connectors\AsyncConnector; -use Barryvdh\Queue\Console\AsyncCommand; +use Illuminate\Queue\QueueManager; use Illuminate\Support\ServiceProvider; class AsyncServiceProvider extends ServiceProvider { - /** - * Indicates if loading of the provider is deferred. - * - * @var bool - */ - protected $defer = false; - /** * Add the connector to the queue drivers. * * @return void */ - public function boot() - { - $this->registerAsyncConnector($this->app['queue']); - - $this->commands('command.queue.async'); - } - - /** - * Register the service provider. - * - * @return void - */ public function register() { - $this->registerAsyncCommand(); - } - - /** - * Register the queue listener console command. - * - * - * @return void - */ - protected function registerAsyncCommand() - { - $this->app->singleton('command.queue.async', function () { - return new AsyncCommand($this->app['queue.worker']); - }); + $this->registerAsyncConnector(); } /** * Register the Async queue connector. * - * @param \Illuminate\Queue\QueueManager $manager - * * @return void */ - protected function registerAsyncConnector($manager) + protected function registerAsyncConnector() { - $manager->addConnector('async', function () { - return new AsyncConnector($this->app['db']); + $this->callAfterResolving(QueueManager::class, function ($manager) { + $manager->addConnector('async', function () { + return new AsyncConnector; + }); }); } - - /** - * Get the services provided by the provider. - * - * @return array - */ - public function provides() - { - return ['command.queue.async']; - } } diff --git a/src/Connectors/AsyncConnector.php b/src/Connectors/AsyncConnector.php index e725797..9963ed5 100644 --- a/src/Connectors/AsyncConnector.php +++ b/src/Connectors/AsyncConnector.php @@ -3,29 +3,15 @@ namespace Barryvdh\Queue\Connectors; use Barryvdh\Queue\AsyncQueue; -use Illuminate\Queue\Connectors\DatabaseConnector; -use Illuminate\Support\Arr; +use Illuminate\Queue\Connectors\SyncConnector; -class AsyncConnector extends DatabaseConnector +class AsyncConnector extends SyncConnector { - /** - * Establish a queue connection. - * - * @param array $config - * - * @return \Illuminate\Contracts\Queue\Queue + * {@inheritdoc} */ public function connect(array $config) { - return new AsyncQueue( - $this->connections->connection(Arr::get($config, 'connection')), - $config['table'], - $config['queue'], - Arr::get($config, 'expire', 60), - Arr::get($config, 'binary', 'php'), - Arr::get($config, 'binary_args', ''), - Arr::get($config, 'connection_name', '') - ); + return new AsyncQueue($config['after_commit'] ?? null); } } diff --git a/src/Console/AsyncCommand.php b/src/Console/AsyncCommand.php deleted file mode 100644 index 1950e98..0000000 --- a/src/Console/AsyncCommand.php +++ /dev/null @@ -1,99 +0,0 @@ -worker = $worker; - } - - /** - * Execute the console command. - * - * @param WorkerOptions $options - * @return void - */ - public function handle(WorkerOptions $options) - { - $id = $this->argument('id'); - $connection = $this->argument('connection'); - - $this->processJob( - $connection, $id, $options - ); - } - - /** - * Process the job - * - * @param string $connectionName - * @param integer $id - * @param WorkerOptions $options - * - * @throws \Throwable - */ - protected function processJob($connectionName, $id, $options) - { - $manager = $this->worker->getManager(); - - /** @var AsyncQueue $connection */ - $connection = $manager->connection($connectionName); - - $job = $connection->getJobFromId($id); - - if ( ! is_null($job)) { - $this->worker->process( - $manager->getName($connectionName), $job, $options - ); - } - } - - /** - * Get the console command arguments. - * - * @return array - */ - protected function getArguments() - { - return [ - ['id', InputArgument::REQUIRED, 'The Job ID'], - ['connection', InputArgument::OPTIONAL, 'The name of connection'], - ]; - } -}