我调用一个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)以使作业在Horizo​​n中显示为“失败”。

关于php - Laravel队列-在特定条件下防止作业重试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63353987/

10-16 12:38