【问题标题】:Laravel Queued Job, Execute it before its execution timeLaravel 排队作业,在其执行时间之前执行它
【发布时间】:2020-03-05 10:07:42
【问题描述】:

我创建了一个在特定日期和时间(例如明天)执行的 Laravel 作业。我想添加一个手动按钮,它会覆盖时间并在其设置的执行时间之前执行该排队的作业。 单击该按钮会创建一个 ajax 调用并将一个作业 ID 发送到服务器。这将导致今天而不是明天执行的作业。

我们可以使用以下命令手动重试失败的作业: php artisan queue:retry JOBIDHERE

我不确定使用什么来执行排队的作业。

我可以得到job ID,但不知道Laravel Job是否可以在设定的执行时间之前执行。

我在谷歌上搜索,但没有找到有此类问题和解决方案的人。

我正在使用 Laravel 5.8 版。 使用 MySQL 5.7


更新:

以下是排队作业的负载。

我尝试使用 Json Decode 并对其进行解码,但我不确定是否可以更新该队列的命令,以便我可以更新队列的日期和时间并将其保存回排队的作业记录。

{"displayName":"App\\Jobs\\Payway\\UpdateCustomerInvestment","job":"Illuminate\\Queue\\CallQueuedHandler@call","maxTries":null,"delay":null,"timeout":null,"timeoutAt":null,"data":{"commandName":"App\\Jobs\\Payway\\UpdateCustomerInvestment","command":"O:40:\"App\\Jobs\\Payway\\UpdateCustomerInvestment\":17:{s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000transactionType\";s:7:\"payment\";s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000principalAmount\";d:9999;s:56:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000customerNumber\";s:4:\"BR-2\";s:50:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000currency\";s:3:\"aud\";s:58:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000singleUseTokenID\";N;s:55:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000payway_helper\";O:29:\"App\\Http\\Helpers\\PaywayHelper\":0:{}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000impodenceKey\";s:36:\"afedfc34-d08e-4831-a4aa-29de930d6b98\";s:49:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000headers\";a:0:{}s:60:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000localInvestmentObj\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:33:\"App\\Models\\Investment\\Investments\";s:2:\"id\";i:374;s:9:\"relations\";a:2:{i:0;s:8:\"investor\";i:1;s:13:\"investor.user\";}s:10:\"connection\";s:5:\"mysql\";}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000paywayTotals\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:38:\"App\\Models\\Banking\\Payway\\PaywayTotals\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:5:\"mysql\";}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";s:6:\"payway\";s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";O:13:\"Carbon\\Carbon\":3:{s:4:\"date\";s:26:\"2019-11-12 23:35:22.752222\";s:13:\"timezone_type\";i:3;s:8:\"timezone\";s:16:\"Australia\/Sydney\";}s:7:\"chained\";a:0:{}}"}}

更新 2:

当我反序列化payload命令时,得到如下信息。

所以我正在尝试更新该延迟日期,希望它会起作用。

但从“朱利安·斯塔克”的回答来看,我可能还需要更新 available_at。

我的理论是当队列运行时,它会根据available_at 寻找工作。但是,当作业正在执行并且它有延迟时,它可能不会在那个特定时间执行。这个理论还有待检验。

我将更新这两个日期时间并检查一切是否顺利。

【问题讨论】:

    标签: php mysql laravel


    【解决方案1】:

    在类似的用例中,我只是更新了作业available_at 的时间,所以queue:listen 命令会尽快执行作业。

    DB::table('jobs')->where('id', $jobId)->update(['available_at' => time()]);
    

    我不知道这是否是正确的做法,但它对我有用

    【讨论】:

    • 用新发现更新了我的问题。请检查这些。感谢您提及 available_at。
    • 我在 laravel 5.8 中测试了我的示例,没有修改 payload 延迟并且作业执行,所以你在更新 2 中提到的理论是错误的
    • 为了确定,我会将time() 更改为DB::raw('NOW()')
    【解决方案2】:

    更新排队作业的时间将是不好的做法,而不是您可以刷新计划的作业并运行立即调度功能。

    【讨论】:

    • 这也可以。你我不确定为什么另一种方法是不好的做法?两种方法对我来说都很好,直接更新日期或删除现有的并再次创建工作。但我想看看我们如何更新现有工作的日期/时间。
    【解决方案3】:

    要实现这一点,您所要做的就是首先解码您的有效载荷,这将是

    {
       "displayName":"App\\Jobs\\Payway\\UpdateCustomerInvestment",
       "job":"Illuminate\\Queue\\CallQueuedHandler@call",
       "maxTries":null,
       "delay":null,
       "timeout":null,
       "timeoutAt":null,
       "data":{
          "commandName":"App\\Jobs\\Payway\\UpdateCustomerInvestment",
          "command":"O:40:\"App\\Jobs\\Payway\\UpdateCustomerInvestment\":17:{s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000transactionType\";s:7:\"payment\";s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000principalAmount\";d:9999;s:56:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000customerNumber\";s:4:\"BR-2\";s:50:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000currency\";s:3:\"aud\";s:58:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000singleUseTokenID\";N;s:55:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000payway_helper\";O:29:\"App\\Http\\Helpers\\PaywayHelper\":0:{}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000impodenceKey\";s:36:\"afedfc34-d08e-4831-a4aa-29de930d6b98\";s:49:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000headers\";a:0:{}s:60:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000localInvestmentObj\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:33:\"App\\Models\\Investment\\Investments\";s:2:\"id\";i:374;s:9:\"relations\";a:2:{i:0;s:8:\"investor\";i:1;s:13:\"investor.user\";}s:10:\"connection\";s:5:\"mysql\";}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000paywayTotals\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:38:\"App\\Models\\Banking\\Payway\\PaywayTotals\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:5:\"mysql\";}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";s:6:\"payway\";s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";O:13:\"Carbon\\Carbon\":3:{s:4:\"date\";s:26:\"2019-11-12 23:35:22.752222\";s:13:\"timezone_type\";i:3;s:8:\"timezone\";s:16:\"Australia\/Sydney\";}s:7:\"chained\";a:0:{}}"
       }
    }
    

    当你解码你的payload后,你会看到“command”被序列化了,所以接下来你要反序列化“command”

    [delay] => Array
            (
                [date] => 2019-11-12 23:35:22.752222
                [timezone_type] => 3
                [timezone] => Australia/Sydney
            )
    

    之后,您可以在 delay 节点下更新日期,并使用 Carbon 或 PHP 日期,根据需要更新日期。 完成后,您只需要再次序列化 "command" 节点,然后json_encode 整个有效载荷并保存。

    您还需要遵循@Julian Stark 的回答,即修改该工作的available_at

    我希望这会有所帮助。

    【讨论】:

    • 我已经按照相同的流程更新了两个日期。已经完美地工作了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 2018-11-30
    • 2019-11-28
    • 2016-09-01
    • 1970-01-01
    • 2019-10-30
    • 2013-08-27
    相关资源
    最近更新 更多