Laravel 一旦失败就删除作业
Laravel delete job once it fails
我有一份工作会超时,一旦它失败,它就会像它自己一样调度另一个工作,这样它就可以 运行 无限且不重叠。然而,失败的工作留在队列中并重新尝试,所以我最终有不止一份工作 运行ning 打破了整个目的。
以下是我处理作业失败的方式:
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
//infinite websocket listening loop
}
public function failed(Exception $exception)
{
$this::dispatch()->onQueue('long-queue');
$this->delete();
}
$this->delete()
来自 InteractsWithQueue
特质。我做错了什么?
编辑:
我正在使用 horizon 来处理 运行 作业,这里是 config/horizon.php
中设置的自定义队列的配置
'supervisor-long' => [
'connection' => 'redis-long',
'queue' => ['long-queue'],
'balance' => 'simple',
'processes' => 3,
'tries' => 1,
'timeout' => 3600,
],
我正在分派的工作是创建一个 Thruway 客户端以连接到 Web 套接字服务器并订阅一个频道以获取更新,所以我想永远 运行 这个工作,但只有 运行 此作业的一个实例随时可用。这就是为什么我希望它在没有任何尝试的情况下 运行 一次,一旦它超时调度另一个将 运行 并且循环将继续的实例。我想不出更好的方法来实现这一点,还有其他更好的方法吗?
失败不执行的原因,只有在作业超过最大尝试次数时才会触发。流程看起来像这样。
$job->dispatch(); // try 1
// times out
// retries on try 2 now
// times out
// retries on try 3 now
// max attempt is hit and MaxAttempt exception is thrown
// failed is called
如果你的作业真的崩溃了,这个逻辑就会改变,这个例子只是在它无限期运行的时候。逻辑是 handled.
在 config/horizon 中的队列定义中。php 您可以定义尝试。
'my-short-queue' => [
'connection' => 'redis',
'queue' => ['my-short-queue'],
'balance' => 'simple',
'processes' => 1,
'tries' => 1,
]
原来我的作业没有失败,所以 failed()
方法没有被执行。即使您在 config/horizon.php
文件中将尝试设置为 tries => 1
,您也需要在 config/queue.php
文件中将 retry_after
值设置为 0
,以便作业失败就在它超时之后。这样您的 failed()
方法就会立即被调用。您可以在下面找到我的配置文件的最终形式。
config/queue.php
:
'redis-long' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'long-queue',
'retry_after' => 0,
'block_for' => null,
],
config/horizon.php
:
'supervisor-long' => [
'connection' => 'redis-long',
'queue' => ['long-queue'],
'balance' => 'simple',
'processes' => 1,
'tries' => 1,
'timeout' => 3600,
],
发现您实际上可以在排队作业的 failed
方法中执行此操作:
/**
* Handle the failing job.
*
* @param Exception $ex
*
* @return void
*/
public function failed(Exception $ex)
{
$this->delete();
}
我有一份工作会超时,一旦它失败,它就会像它自己一样调度另一个工作,这样它就可以 运行 无限且不重叠。然而,失败的工作留在队列中并重新尝试,所以我最终有不止一份工作 运行ning 打破了整个目的。
以下是我处理作业失败的方式:
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
//infinite websocket listening loop
}
public function failed(Exception $exception)
{
$this::dispatch()->onQueue('long-queue');
$this->delete();
}
$this->delete()
来自 InteractsWithQueue
特质。我做错了什么?
编辑:
我正在使用 horizon 来处理 运行 作业,这里是 config/horizon.php
'supervisor-long' => [
'connection' => 'redis-long',
'queue' => ['long-queue'],
'balance' => 'simple',
'processes' => 3,
'tries' => 1,
'timeout' => 3600,
],
我正在分派的工作是创建一个 Thruway 客户端以连接到 Web 套接字服务器并订阅一个频道以获取更新,所以我想永远 运行 这个工作,但只有 运行 此作业的一个实例随时可用。这就是为什么我希望它在没有任何尝试的情况下 运行 一次,一旦它超时调度另一个将 运行 并且循环将继续的实例。我想不出更好的方法来实现这一点,还有其他更好的方法吗?
失败不执行的原因,只有在作业超过最大尝试次数时才会触发。流程看起来像这样。
$job->dispatch(); // try 1
// times out
// retries on try 2 now
// times out
// retries on try 3 now
// max attempt is hit and MaxAttempt exception is thrown
// failed is called
如果你的作业真的崩溃了,这个逻辑就会改变,这个例子只是在它无限期运行的时候。逻辑是 handled.
在 config/horizon 中的队列定义中。php 您可以定义尝试。
'my-short-queue' => [
'connection' => 'redis',
'queue' => ['my-short-queue'],
'balance' => 'simple',
'processes' => 1,
'tries' => 1,
]
原来我的作业没有失败,所以 failed()
方法没有被执行。即使您在 config/horizon.php
文件中将尝试设置为 tries => 1
,您也需要在 config/queue.php
文件中将 retry_after
值设置为 0
,以便作业失败就在它超时之后。这样您的 failed()
方法就会立即被调用。您可以在下面找到我的配置文件的最终形式。
config/queue.php
:
'redis-long' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'long-queue',
'retry_after' => 0,
'block_for' => null,
],
config/horizon.php
:
'supervisor-long' => [
'connection' => 'redis-long',
'queue' => ['long-queue'],
'balance' => 'simple',
'processes' => 1,
'tries' => 1,
'timeout' => 3600,
],
发现您实际上可以在排队作业的 failed
方法中执行此操作:
/**
* Handle the failing job.
*
* @param Exception $ex
*
* @return void
*/
public function failed(Exception $ex)
{
$this->delete();
}