Skip to content

Behavior of defer() has changed #58731

@schursin

Description

@schursin

Laravel Version

v12.45.0

PHP Version

8.3

Database Driver & Version

No response

Description

Starting from v12.45.0, the behavior of defer() has changed.

I assume this happened after "feat: fire JobAttempted for sync jobs too #58228".

Job executes and calls defer(), after the Job completes, the JobAttempted event triggers a listener:

https://github.com/laravel/framework/blob/12.x/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php#L217

The invokeWhen() condition evaluates to false (since it's a sync queue, in this case because it's a test), which leads to the previously set defer-callback being removed from the execution queue.

Before v12.45.0, there was no JobAttempted event, the listener didn't run, and the defer-callback was successfully executed from InvokeDeferredCallbacks middleware.

Steps To Reproduce

<?php

declare(strict_types=1);

namespace Feature;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\Events\JobAttempted;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Route;
use Tests\TestCase;

use function Illuminate\Support\defer;

class TestJob implements ShouldQueue
{
    use Dispatchable;

    public function handle(): void
    {
        dump('handle');

        defer(fn() => dump('defer'))->always();
    }
}

class DeferTest extends TestCase
{
    public function test()
    {
        Event::listen(JobAttempted::class, function (JobAttempted $event) {
            dump('listener');
        });

        Route::get('/test', function () {
            TestJob::dispatch();
        });

        $this->get('/test');
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions