ngmy/laravel-job-response

为 Laravel Jobs 添加响应 - 允许您的应用程序等待从派发的任务中获取响应。

0.5.0 2023-07-17 12:36 UTC

This package is auto-updated.

Last update: 2024-09-17 18:46:44 UTC


README

Latest Stable Version Test Status Lint Status Code Coverage Total Downloads

您是否需要运行 Laravel 任务(或多个任务),等待响应,然后使用该响应?此包正是为此功能而设计的。

安装

您可以通过 Composer 安装此包

composer require ngmy/laravel-job-response

要求

  • PHP >= 8.1
  • Laravel >= 9.0

使用方法

在您的 Job 中使用 CanRespond 特性并实现 JobCanRespond 合约

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Williamjulianvicary\LaravelJobResponse\CanRespond;
use Williamjulianvicary\LaravelJobResponse\Contracts\JobCanRespond;

class TestJob implements ShouldQueue, JobCanRespond
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, CanRespond;

    public function handle(): void
    {
        $this->respond('Success');
    }
}

然后在您的 Service/Controller/其他地方,等待您的任务响应

<?php

namespace App\Services;

use App\Jobs\TestJob;
use Williamjulianvicary\LaravelJobResponse\ExceptionResponse;
use Williamjulianvicary\LaravelJobResponse\Response;

class Service
{
    public function test(): void
    {
        $job = new TestJob();
        /** @var ExceptionResponse|Response $response */
        $response = $job->awaitResponse();

        if ($response instanceof ExceptionResponse) {
            echo $response->getMessage().PHP_EOL; // The exception message string thrown by the job.
        } else {
            echo $response->getData().PHP_EOL; // 'Success'
        }
    }
}

或者,运行多个任务并等待响应

<?php

namespace App\Services;

use App\Jobs\TestJob;
use Williamjulianvicary\LaravelJobResponse\ExceptionResponse;
use Williamjulianvicary\LaravelJobResponse\Facades\LaravelJobResponse;
use Williamjulianvicary\LaravelJobResponse\Response;
use Williamjulianvicary\LaravelJobResponse\ResponseCollection;

class Service
{
    public function test(): void
    {
        $jobs = [new TestJob(), new TestJob()];
        /** @var ResponseCollection<array-key, ExceptionResponse|Response> $responses */
        $responses = LaravelJobResponse::awaitResponses($jobs);

        foreach ($responses as $response) {
            if ($response instanceof ExceptionResponse) {
                echo $response->getMessage().PHP_EOL;
            } else {
                echo $response->getData().PHP_EOL;
            }
        }
    }
}

响应

默认情况下,该包以三种方式响应

  • ResponseCollection - 当预期多个响应时,将返回包含 Response 和/或 ExceptionResponse 对象的 ResponseCollection。
  • Response - 成功的响应对象。
  • ExceptionResponse - 当任务失败时,异常将被捕获并传递回来。

(可选) 处理异常

默认情况下创建一个 ExceptionResponse 对象。然而,这可能会导致一些额外的样板代码来处理它,因此我们提供了一个可选的方法,可以将这些异常重新抛出。

要启用此功能,请使用 Facade 更新 throwExceptionOnFailure 标志

use Williamjulianvicary\LaravelJobResponse\Facades\LaravelJobResponse;

LaravelJobResponse::throwExceptionOnFailure(true);

现在,每当发起一个 await 时,如果遇到来自任务的异常,将引发一个 JobFailedException

<?php

namespace App\Services;

use App\Jobs\TestJob;
use Williamjulianvicary\LaravelJobResponse\Exceptions\JobFailedException;
use Williamjulianvicary\LaravelJobResponse\Facades\LaravelJobResponse;

class Service
{
    public function test(): void
    {
        $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.
        }
    }
}

方法

// 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(int $timeout = 10, bool $throwException = false): ExceptionResponse|Response;

// Should be used within the handle() method of the job to respond appropriately.
$job->respond(mixed $data): void;

// If you override the failed() method, this method responds with an exception.
$job->respondWithException(?\Throwable $exception = null): void;

// Facade methods

// Await a response for the given job.
LaravelJobResponse::awaitResponse(JobCanRespond $job, int $timeout = 10): ExceptionResponse|Response;

// Await responses from the provided job array.
LaravelJobResponse::awaitResponses(JobCanRespond[] $jobs, int $timeout = 10): ResponseCollection<array-key, ExceptionResponse|Response>;

// Change how exceptions are handled (see above).
LaravelJobResponse::throwExceptionOnFailure(bool $flag = false): self;

故障排除

在使用此包时,您可能会遇到 Laravel 中的一些奇怪之处

  • 当使用 sync 驱动程序运行时,异常不会被捕获 - 这是因为 Laravel 并未在 Sync 驱动程序中本地捕获它们,并且我们的包无法捕获它们。如果您需要使用此驱动程序处理异常,请改用 $job->fail($exception);

测试

composer test

变更日志

有关最近更改的更多信息,请参阅 CHANGELOG

贡献

有关详细信息,请参阅 CONTRIBUTING

鸣谢

许可证

MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件