LaravelのConcurrencyファサードで並列処理を簡単に!
LaravelのConcurrencyファサードで並列処理を簡単に!
Laravel 11.23から導入されたConcurrencyファサードを使うと、複数の独立したタスクを同時に実行でき、アプリケーションのパフォーマンスを向上させることができます。
例えば、外部APIからユーザー情報と注文情報を取得する際、従来は順番にリクエストを送っていましたが、Concurrencyを使えばこれらを並列に処理できます。
Concurrencyファサードの基本
Concurrency::run() メソッドを使うと、複数の処理を並列で実行できます。
以下の例では、ユーザー情報と注文情報を同時に取得しています。
<?php
use Illuminate\Support\Facades\Concurrency;
use Illuminate\Support\Facades\Http;
[$userData, $orderData] = Concurrency::run([
fn() => Http::get('https://api.example.com/users')->json(),
fn() => Http::get('https://api.example.com/orders')->json(),
]);
この方法のメリット
-
処理時間の短縮
従来の同期処理では、リクエストが順番に実行されるため、合計の処理時間が長くなりがちでした。
Concurrency::run()を使えば、複数のリクエストを並列実行でき、全体の処理時間を短縮できます。 -
シンプルなコード
並列処理を実装するために、キューやジョブを使う必要がなく、シンプルなコードで済みます。
Concurrencyの実行ドライバ
Concurrencyファサードでは、処理の方法を選択できます。
デフォルトのprocessのほかに、forkやsyncといったドライバもサポートされています。
| ドライバ | 特徴 |
|---|---|
| process | デフォルトの並列実行方式 |
| fork |
spatie/fork を使用し、高速な処理が可能 |
| sync | 並列処理せずに同期的に実行 |
forkドライバを使用する場合は、事前に以下のパッケージをインストールしてください。
composer require spatie/fork
Concurrencyファサードのdriver`メソッドを使用して実行ドライバを変更できます。
use Illuminate\Support\Facades\Concurrency;
// `fork`ドライバを使用
Concurrency::driver('fork')->run([
fn () => heavyTask1(),
fn () => heavyTask2(),
]);
// `sync`ドライバを使用
Concurrency::driver('sync')->run([
fn () => task1(),
fn () => task2(),
]);
デフォルトのprocessドライバを明示的に指定することも可能です。
Concurrency::driver('process')->run([
fn () => taskA(),
fn () => taskB(),
]);
driverメソッドを使用することで、状況に応じた最適な実行方式を選択できます。
Concurrency::defer() でバックグラウンド処理を実行
レスポンスをすぐに返したいが、後処理も並列で実行したい場合は、Concurrency::defer() を使うと便利です。
例えば、メトリクスデータの集計処理をバックグラウンドで行いたい場合、以下のように記述できます。
<?php
use Illuminate\Support\Facades\Concurrency;
use App\Services\Metrics;
Concurrency::defer([
fn() => Metrics::report('users'),
fn() => Metrics::report('orders'),
]);
Concurrency::defer() の利点
-
ユーザーに素早くレスポンスを返せる
処理をバックグラウンドで実行できるため、フロントエンドの待ち時間を短縮できます。 -
並列実行が可能
defer()内の複数のタスクも、run()と同じように並列で実行されます。
Discussion