Concurrency
Introducción
La fachada de Concurrency
de Laravel está actualmente en beta mientras recopilamos comentarios de la comunidad.
A veces, puede que necesites ejecutar varias tareas lentas que no dependen unas de otras. En muchos casos, se pueden lograr mejoras significativas en el rendimiento ejecutando las tareas de manera concurrente. La fachada de Concurrency
de Laravel proporciona una API simple y conveniente para ejecutar cierres de manera concurrente.
Compatibilidad de Concurrency
Si actualizaste a Laravel 11.x desde una aplicación Laravel 10.x, es posible que necesites agregar el ConcurrencyServiceProvider
al array de proveedores en el archivo de configuración config/app.php
de tu aplicación:
'providers' => ServiceProvider::defaultProviders()->merge([
/*
* Proveedores de servicios de paquetes...
*/
Illuminate\Concurrency\ConcurrencyServiceProvider::class,
/*
* Proveedores de servicios de la aplicación...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
])->toArray(),
Cómo Funciona
Laravel logra la concurrencia serializando los cierres dados y enviándolos a un comando CLI de Artisan oculto, que deserializa los cierres y los invoca dentro de su propio proceso PHP. Después de que el cierre ha sido invocado, el valor resultante se serializa de vuelta al proceso principal.
La fachada de Concurrency
soporta tres controladores: process
(el predeterminado), fork
y sync
.
El controlador fork
ofrece un mejor rendimiento en comparación con el controlador de proceso predeterminado, pero solo puede usarse dentro del contexto CLI de PHP, ya que PHP no soporta bifurcación durante las solicitudes web. Antes de usar el controlador fork
, necesitas instalar el paquete spatie/fork
:
composer require spatie/fork
El controlador sync
es principalmente útil durante las pruebas cuando deseas deshabilitar toda la concurrencia y simplemente ejecutar los cierres dados en secuencia dentro del proceso principal.
Ejecutando Tareas Concurrentes
Para ejecutar tareas concurrentes, puedes invocar el método run
de la fachada Concurrency
. El método run
acepta un array de cierres que deben ejecutarse simultáneamente en procesos PHP hijos:
use Illuminate\Support\Facades\Concurrency;
use Illuminate\Support\Facades\DB;
[$userCount, $orderCount] = Concurrency::run([
fn () => DB::table('users')->count(),
fn () => DB::table('orders')->count(),
]);
Para usar un controlador específico, puedes usar el método driver
:
$results = Concurrency::driver('fork')->run(...);
O, para cambiar el controlador de concurrencia predeterminado, debes publicar el archivo de configuración de concurrencia a través del comando Artisan config:publish
y actualizar la opción predeterminada dentro del archivo:
php artisan config:publish concurrency
Diferir Tareas Concurrentes
Si deseas ejecutar un array de cierres de manera concurrente, pero no estás interesado en los resultados devueltos por esos cierres, deberías considerar usar el método defer
. Cuando se invoca el método defer
, los cierres dados no se ejecutan inmediatamente. En su lugar, Laravel ejecutará los cierres de manera concurrente después de que la respuesta HTTP haya sido enviada al usuario:
use App\Services\Metrics;
use Illuminate\Support\Facades\Concurrency;
Concurrency::defer([
fn () => Metrics::report('users'),
fn () => Metrics::report('orders'),
]);