7.5 KiB
Job Entrypoint (dispatch, asJob)
Scope
Use this reference when running an action through queues.
Recap
- Lists async/sync dispatch helpers and conditional dispatch variants.
- Covers job wrapping/chaining with
makeJob,makeUniqueJob, andwithChain. - Documents queue assertion helpers for tests (
assertPushed*). - Summarizes
JobDecoratorhooks/properties for retries, uniqueness, timeout, and failure handling.
Recommended pattern
- Dispatch with
Action::dispatch(...)for async execution. - Keep queue-specific orchestration in
asJob(...). - Keep reusable business logic in
handle(...).
Methods provided (AsJob trait)
dispatch
Dispatches the action asynchronously.
SendTeamReportEmail::dispatch($team);
dispatchIf
Dispatches asynchronously only if condition is met.
SendTeamReportEmail::dispatchIf($team->plan === 'premium', $team);
dispatchUnless
Dispatches asynchronously unless condition is met.
SendTeamReportEmail::dispatchUnless($team->plan === 'free', $team);
dispatchSync
Dispatches synchronously.
SendTeamReportEmail::dispatchSync($team);
dispatchNow
Alias of dispatchSync.
SendTeamReportEmail::dispatchNow($team);
dispatchAfterResponse
Dispatches synchronously after the HTTP response is sent.
SendTeamReportEmail::dispatchAfterResponse($team);
makeJob
Creates a JobDecorator wrapper. Useful with dispatch(...) helper or chains.
dispatch(SendTeamReportEmail::makeJob($team));
makeUniqueJob
Creates a UniqueJobDecorator wrapper. Usually automatic with ShouldBeUnique, but can be forced.
dispatch(SendTeamReportEmail::makeUniqueJob($team));
withChain
Attaches jobs to run after successful processing.
$chain = [
OptimizeTeamReport::makeJob($team),
SendTeamReportEmail::makeJob($team),
];
CreateNewTeamReport::withChain($chain)->dispatch($team);
Equivalent using Bus::chain(...):
use Illuminate\Support\Facades\Bus;
Bus::chain([
CreateNewTeamReport::makeJob($team),
OptimizeTeamReport::makeJob($team),
SendTeamReportEmail::makeJob($team),
])->dispatch();
Chain assertion example:
use Illuminate\Support\Facades\Bus;
Bus::fake();
Bus::assertChained([
CreateNewTeamReport::makeJob($team),
OptimizeTeamReport::makeJob($team),
SendTeamReportEmail::makeJob($team),
]);
assertPushed
Asserts the action was queued.
use Illuminate\Support\Facades\Queue;
Queue::fake();
SendTeamReportEmail::assertPushed();
SendTeamReportEmail::assertPushed(3);
SendTeamReportEmail::assertPushed($callback);
SendTeamReportEmail::assertPushed(3, $callback);
$callback receives:
- Action instance.
- Dispatched arguments.
JobDecoratorinstance.- Queue name.
assertNotPushed
Asserts the action was not queued.
use Illuminate\Support\Facades\Queue;
Queue::fake();
SendTeamReportEmail::assertNotPushed();
SendTeamReportEmail::assertNotPushed($callback);
assertPushedOn
Asserts the action was queued on a specific queue.
use Illuminate\Support\Facades\Queue;
Queue::fake();
SendTeamReportEmail::assertPushedOn('reports');
SendTeamReportEmail::assertPushedOn('reports', 3);
SendTeamReportEmail::assertPushedOn('reports', $callback);
SendTeamReportEmail::assertPushedOn('reports', 3, $callback);
Methods used (JobDecorator)
asJob
Called when dispatched as a job. Falls back to handle(...) if missing.
class SendTeamReportEmail
{
use AsAction;
public function handle(Team $team, bool $fullReport = false): void
{
// Prepare report and send it to all $team->users.
}
public function asJob(Team $team): void
{
$this->handle($team, true);
}
}
getJobMiddleware
Adds middleware to the queued action.
public function getJobMiddleware(array $parameters): array
{
return [new RateLimited('reports')];
}
configureJob
Configures JobDecorator options.
use Lorisleiva\Actions\Decorators\JobDecorator;
public function configureJob(JobDecorator $job): void
{
$job->onConnection('my_connection')
->onQueue('my_queue')
->through(['my_middleware'])
->chain(['my_chain'])
->delay(60);
}
$jobConnection
Defines queue connection.
public string $jobConnection = 'my_connection';
$jobQueue
Defines queue name.
public string $jobQueue = 'my_queue';
$jobTries
Defines max attempts.
public int $jobTries = 10;
$jobMaxExceptions
Defines max unhandled exceptions before failure.
public int $jobMaxExceptions = 3;
$jobBackoff
Defines retry delay seconds.
public int $jobBackoff = 60;
getJobBackoff
Defines retry delay (int or per-attempt array).
public function getJobBackoff(): int
{
return 60;
}
public function getJobBackoff(): array
{
return [30, 60, 120];
}
$jobTimeout
Defines timeout in seconds.
public int $jobTimeout = 60 * 30;
$jobRetryUntil
Defines timestamp retry deadline.
public int $jobRetryUntil = 1610191764;
getJobRetryUntil
Defines retry deadline as DateTime.
public function getJobRetryUntil(): DateTime
{
return now()->addMinutes(30);
}
getJobDisplayName
Customizes queued job display name.
public function getJobDisplayName(): string
{
return 'Send team report email';
}
getJobTags
Adds queue tags.
public function getJobTags(Team $team): array
{
return ['report', 'team:'.$team->id];
}
getJobUniqueId
Defines uniqueness key when using ShouldBeUnique.
public function getJobUniqueId(Team $team): int
{
return $team->id;
}
$jobUniqueId
Static uniqueness key alternative.
public string $jobUniqueId = 'some_static_key';
getJobUniqueFor
Defines uniqueness lock duration in seconds.
public function getJobUniqueFor(Team $team): int
{
return $team->role === 'premium' ? 1800 : 3600;
}
$jobUniqueFor
Property alternative for uniqueness lock duration.
public int $jobUniqueFor = 3600;
getJobUniqueVia
Defines cache driver used for uniqueness lock.
public function getJobUniqueVia()
{
return Cache::driver('redis');
}
$jobDeleteWhenMissingModels
Property alternative for missing model handling.
public bool $jobDeleteWhenMissingModels = true;
getJobDeleteWhenMissingModels
Defines whether jobs with missing models are deleted.
public function getJobDeleteWhenMissingModels(): bool
{
return true;
}
jobFailed
Handles job failure. Receives exception and dispatched parameters.
public function jobFailed(?Throwable $e, ...$parameters): void
{
// Notify users, report errors, trigger compensations...
}
Checklist
- Async/sync dispatch method matches use-case (
dispatch,dispatchSync,dispatchAfterResponse). - Queue config is explicit when needed (
$jobConnection,$jobQueue,configureJob). - Retry/backoff/timeout policies are intentional.
asJob(...)delegates tohandle(...)unless queue-specific branching is required.- Queue tests use
Queue::fake()and action assertions (assertPushed*).
Common pitfalls
- Embedding domain logic only in
asJob(...). - Forgetting uniqueness/timeout/retry controls on heavy jobs.
- Missing queue-specific assertions in tests.