Have you ever needed to run a Laravel job (or multiple jobs), wait for the response and then use that response? This is exactly the functionality this package provides.
You can install the package via composer:
composer require williamjulianvicary/laravel-job-response
- PHP >= 7.4
- Laravel >= 7.0 (While not tested on prior versions may work)
In your Job
use the CanRespond
trait and add implement the JobCanRespond
contract.
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Williamjulianvicary\LaravelJobResponse\CanRespond;
use Williamjulianvicary\LaravelJobResponse\Contracts\JobCanRespond;
class TestJob implements ShouldQueue, JobCanRespond
{
use InteractsWithQueue, Queueable, Dispatchable, CanRespond;
public function __construct()
{
}
public function handle()
{
$this->respond('Success');
}
}
Then in your Service/Controller/elsewhere, await a response from your job.
<?php
namespace App\Services;
class Service
{
public function test()
{
$job = new TestJob();
$response = $job->awaitResponse();
// $response is an instance of Response or ExceptionResponse
$data = $response->getData(); // 'Success'
// or
$exception = $response; // JobFailedException
}
}
Or alternatively, run multiple jobs and await the responses
<?php
namespace App\Services;
namespace Williamjulianvicary\LaravelJobResponse\Facades\LaravelJobResponse;
class Service
{
public function test()
{
$jobs = [new TestJob(), new TestJob()];
$responses = LaravelJobResponse::awaitResponses($jobs); // ResponseCollection
foreach ($responses as $response) {
if ($response instanceof ExceptionResponse) {
echo "Exception: " . $response->getMessage() . "\n";
} else {
echo "Response: " . $response->getData() . "\n";
}
}
}
}
By default, the package responds in three ways:
ResponseCollection
- When multiple responses are expected, a ResponseCollection will be returned containingResponse
and/orExceptionResponse
objects.Response
- A successful response object.ExceptionResponse
- When a job fails the exception is caught and passed back.
By default a ExceptionResponse
object is created with a $exceptionResponse->getException()
method available to allow you to
review the exception thrown from the Job. However, this can lead to some extra boilerplate code to handle this, so instead we've
an optional method available that will re-throw these exceptions.
To enable this, use the Facade to update the throwExceptionsOnFailures
flag
use Williamjulianvicary\LaravelJobResponse\Facades\LaravelJobResponse;
[...]
LaravelJobResponse::throwExceptionsOnFailures(true);
Now whenever a await is issued, if an exception is encountered from the job, a JobFailedException
will be raised:
<?php
namespace App\Services;
use Williamjulianvicary\LaravelJobResponse\Facades\LaravelJobResponse;
use Williamjulianvicary\LaravelJobResponse\Exceptions\JobFailedException;
class Service
{
public function test()
{
$jobs = [new TestJob(), new TestJob()];
try {
$responses = LaravelJobResponse::awaitResponses($jobs);
} catch (JobFailedException $exception) {
// One of the jobs failed.
$exception->getTrace(); // The exception trace string thrown by the job.
}
}
}
<?php
// Methods available on your jobs
// Await a response for this job, optionally accepts a timeout and bool whether a exception should be raised if the job fails.
// Responds with either Response or ExceptionResponse objects.
$job->awaitResponse($timeout = 10, $throwException = false);
$job->respond($mixed); // Should be used within the handle() method of the job to respond appropriately.
$job->respondWithException(\Throwable); // If you override the failed() method, this method responds with an exception.
// Facade methods
// Await a response for the given job.
LaravelJobResponse::awaitResponse(JobCanRespond $job, $timeout=10);
// Await responses from the provided job array.
LaravelJobResponse::awaitResponses(array $jobs, $timeout=10);
// Change how exceptions are handled (see above).
LaravelJobResponse::throwExceptionOnFailure(false);
There are a few quirks within Laravel that you may run into with this package.
- When running with a
sync
driver, Exceptions will not be caught - this is because Laravel does not natively catch them with the Sync driver and it is impossible for our package to pick them up. If you need to handle exceptions with this driver, use$job->fail($exception);
instead.
composer test
Please see CHANGELOG for more information what has changed recently.
Please see CONTRIBUTING for details.
The MIT License (MIT). Please see License File for more information.