我调用一个API发送短信,并使用Redis::throttle保存其响应,以将调用率限制为每60s使用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中显示为“失败”。关于php - Laravel队列-在特定条件下防止作业重试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63353987/