Invokable > 戻る
2022-12-13
Laravel

Laravel10 DispatchNow削除後に備える

非推奨になっていたJob::dispatchNow()dispatch_now()がLaravel 10で削除される。

  1. 問題ない使い方
  2. 問題になる使い方
  3. 対処方法

問題ない使い方

TestJob::dispatchNow();
dispatch_now(new TestJob());

Syncに書き換えるだけでいい。Laravel9の内に書き換えておく。

TestJob::dispatchSync();
dispatch_sync(new TestJob());

問題になる使い方

dispatchNow()は同期的に実行したジョブから返り値を取得できる。

$test = TestJob::dispatchNow();
$test = dispatch_now(new TestJob());

Syncでは取得できない。「ジョブの実行に成功したかどうか」の結果が帰ってくる。

$test = TestJob::dispatchSync();
$test = dispatch_sync(new TestJob());
dd($test);
// 0

さらに細かい話で「JobクラスにInteractsWithQueueかQueueableがなければ返り値を取得できる」

こんなJobクラスなら以前のdispatchNow()と同じ使い方はできる。

class DispatchSyncReturnJob
{
    use Dispatchable, SerializesModels;

    public function handle(): string
    {
        return 'test';
    }
}

テストコードで書けばこう。

    public function test_sync()
    {
        $res = DispatchSyncReturnJob::dispatchSync();
        $this->assertSame('test', $res);

        $res = DispatchSyncNoReturnJob::dispatchSync();
        $this->assertNotSame('test', $res);
        $this->assertSame(0, $res);
    }

トレイトの有無で変わるので使用時に選べない。

//ここでは同期で返り値を得る。
$test = TestJob::dispatchSync();

//別の場所では非同期で実行。
TestJob::dispatch();
  • 同じJobクラスを同期・非同期で使い分けはできない。
  • 同期でしか使わないJobなら返り値を得る使い方も一応使い続けられる。

対処方法

「Jobクラスから返り値を得るって使い方を捨てる」

本来のJobはキューに投げて非同期で実行するための機能なので返り値を得る使い方は正しくない。スパッと切り捨て。

代わりの手段は難しく考える必要はなくただのクラスとして作る。

class Test
{
    public function __invoke(string $test): string
    {
        return $test;
    }
}

置く場所はapp/Test/Test.phpでもapp/Actions/Test.phpでも好きな場所に置けばいい。

使う時は

use App\Test\Test;

$test = 'hello';
$res = app()->call(Test::class, compact('test'));
dd($res);
// hello

サービスコンテナから実行すればDI含めてJobと同じような動作。

call()での引数の指定は分かりやすくないのでこれでもいい。

$res = app(Test::class)($test);

引数もサービスコンテナからでもいいけどどんどん分かりにくくなる。

$res = app(Test::class)(app(Request::class));

テストではBus::fake()などが使えないので普通にモック。

$this->mock(Test::class, function ($mock) {
    $mock->shouldReceive('__invoke')->once()->andReturn('test');
})
投稿者 Invokable
0件のコメントを読むにはログインしてください。
登録 ログイン