Reputation: 411
I call an API to send SMS and save it's response using Redis::throttle to limit the rate of the call to 5 calls every 60s with :
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
});
I didn't specify any $tries
because if the lock cannot be obtain, it count as a try and if I process a long queue and the lock cannot be obtain many time the job will fail without any "real" errors.
But I dont want the job to be processed forever, if there is a real error (like if the response cannot be saved) it should fail without retry especially if the error appends after the API call as a retry will send another SMS (which I definitely don't want).
What I've tried :
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
});
If there is an exception because the lock cannot be obtain, I throw it back to let the queue handle it but if it's another exception, I log the error and fail or delete the job.
But it's not working with either delete()
or fail()
, the job is always retried.
How can I remove the job if there is an exception other than the LimiterTimeoutException
?
Upvotes: 1
Views: 4737
Reputation: 411
I was missing a "\" before Exception in my catch. Here is the fix code :
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
});
I added $this->fail($exception)
to make the job to show up as "failed" in Horizon.
Upvotes: 1