如何解决Laravel队列-在特定条件下防止作业重试
我调用一个API发送短信并使用Redis :: throttle保存它的响应,以限制每60秒使用5次调用的速率:
Redis::throttle('throttle:sms')->allow(5)->every(60)->then(function(){
//->API call
//->Save response
},function($error){//could not obtain lock
return $this->release(60);//Put back in queue in 60s
});
我没有指定任何$tries
,因为如果无法获得该锁,则将其视为一次尝试,并且如果我处理一个长队列并且无法多次获得该锁,则该作业将在没有任何“真正”的情况下失败错误。
但是我不希望该作业永远被处理,如果存在真正的错误(例如无法保存响应),它将失败而无需重试,特别是如果错误在API调用后附加,因为重试将发送另一个SMS(我绝对不要)。
我尝试过的:
Redis::throttle('throttle')->allow(5)->every(60)->then(function(){
try{
$response = MyAPICall();
$test = 8/0;
saveResponse($response);
} catch(\LimiterTimeoutException $e){
throw $e;
} catch(Exception $e){
Log::error($e);
$this->fail($exception = null);
//$this->delete();
}
},function($error){//could not obtain lock
Log::info($error);
return $this->release(60);//Put back in queue in 60s
});
如果由于无法获取锁而发生异常,我将其扔回去让队列处理它,但是如果是另一个异常,我将记录错误并失败或删除作业。
但是它不能与delete()
或fail()
一起使用,该作业将始终重试。
如果存在LimiterTimeoutException
以外的异常,我该如何删除作业?
解决方法
我在捕获中的异常之前缺少“ \”。这是修复代码:
Redis::throttle('throttle:sms')->allow(5)->every(60)->then(function(){
$response = myAPICall();
try{
$test = 8/0;
SaveResponse($response);
}
catch (LimiterTimeoutException $exception){
throw $exception;//throw back exception to let redis handle it below
}
catch (\Exception $exception) {
Log::error($exception);
$this->fail($exception);
}
},function($error){//could not obtain lock
return $this->release(60);//Put back in queue in 60s
});
我添加了$this->fail($exception)
,以使作业在Horizon中显示为“失败”。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。