Laravel作业队列立即分派现在不像正常情况下那样失败。

huangapple go评论73阅读模式
英文:

Laravel Job Queue Dispatch Now not failing like normal

问题

I have a job that I've made to test how failures work:

<?php

namespace App\Jobs;

use App\ApiUser;
use App\Helpers\Helper;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class FakeJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $apiUser;

    public function __construct(ApiUser $apiUser) {
        $this->apiUser = $apiUser;
    }

    public function handle() {
        throw new Exception('time is even');
    }

    public function failed(Exception $exception) {
        // Send user notification of failure, etc...
        $path = storage_path('logs/s3_logs/FakeJob_failed_' . Helper::generateRandomString(5) . '.txt');
        file_put_contents($path, $exception->getMessage());
    }
}

However when I do it like FakeJob::dispatchNow($apiUser);, it doesn't do that at all...

Is there a way to do dispatchNow that runs on the same process as the request, but fails as if it were queued normally?

Because at the moment, it looks like my only way is to do something like:

$fakeJob = new FakeJob($apiUser);
try {
    $fakeJob->handle();
} catch(Exception $e) {
    $fakeJob->failed($e);
}

Which is... fine I guess, but not ideal.

英文:

I have a job that I've made to test how failures work:

&lt;?php

namespace App\Jobs;

use App\ApiUser;
use App\Helpers\Helper;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class FakeJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $apiUser;

    public function __construct(ApiUser $apiUser) {
        $this-&gt;apiUser = $apiUser;
    }

    public function handle() {
        throw new Exception(&#39;time is even&#39;);
    }

    public function failed(Exception $exception) {
        // Send user notification of failure, etc...
        $path = storage_path(&#39;logs/s3_logs/FakeJob_failed_&#39; . Helper::generateRandomString(5) . &#39;.txt&#39;);
        file_put_contents($path, $exception-&gt;getMessage());
    }
}

When I dispatch normally, it goes to the failed function and writes to file exactly as expected.

However when I do it like FakeJob::dispatchNow($apiUser);, it doesn't do that at all...

Is there a way to do dispatchNow that runs on the same process as the request, but fails as if it were queued normally?

Because at the moment, it looks like my only way is to do something like:

    $fakeJob = new FakeJob($apiUser);
    try {
        $fakeJob-&gt;handle();
    } catch(Exception $e) {
        $fakeJob-&gt;failed($e);
    }

Which is... fine I guess, but not ideal.

答案1

得分: 9

如果我没错,dispatchNow() 用于同步运行作业,但不幸的是,它不会调用失败的方法。

如果你想在作业失败时调用失败方法,你可以使用下面的代码:

FakeJob::dispatch($apiUser)->onConnection('sync');

它将以同步方式运行作业,并执行失败方法。

英文:

If I am not wrong dispatchNow() is used to run the job synchronously but unfortunately, it does not call the failed method.

If you want your failed method to be called on job failed then you can use the below code.

FakeJob::dispatch($apiUser)-&gt;onConnection(&#39;sync&#39;);

It will run the job synchronously and also execute the failed method.

答案2

得分: 4

dispatchNow() 方法在不与任何队列交互的情况下同步执行作业,并且仅仅会调用作业的 handle() 方法,你对 try/catch 块的处理可能是目前最好的解决方案,但考虑向 Laravel 团队提出此功能请求也许是值得的。

英文:

Looking at the Laravel code base (and docs), the dispatchNow() method executes the job synconously without interacting with any queues.

https://laravel.com/docs/5.8/queues#synchronous-dispatching

In essence it will simply call the handle() method on your job and nothing more.

What you have done with your try/catch block may be the best solution for now but it could be worth raising this as a feature request with the Laravel team.

答案3

得分: 4

A new dispatchSync() method will be made available in Laravel 8.0 when it is released in the coming months. It'll dispatch the job on the sync queue just like @Keshari's answer suggests.

Docs: https://laravel.com/docs/master/queues#synchronous-dispatching
Commit: https://github.com/laravel/framework/commit/0b3ed6859046258fba2e0ab3340bdab33e4c82bd

英文:

A new dispatchSync() method will be made available in Laravel 8.0 when it is released in the coming months.
It'll dispatch the job on the sync queue just like @Keshari's answer suggests.

Docs: https://laravel.com/docs/master/queues#synchronous-dispatching
Commit: https://github.com/laravel/framework/commit/0b3ed6859046258fba2e0ab3340bdab33e4c82bd

huangapple
  • 本文由 发表于 2020年1月3日 20:52:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/59578987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定