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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...