英文:
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:
<?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());
}
}
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->handle();
} catch(Exception $e) {
$fakeJob->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)->onConnection('sync');
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论