【问题标题】:Queue manager with nested closures, commands, and dependencies具有嵌套闭包、命令和依赖项的队列管理器
【发布时间】:2013-05-29 23:55:27
【问题描述】:

我对 Laravel 很陌生,我正在尝试创建队列来处理我的处理脚本。 处理脚本将由每晚的 cron 作业触发。

我已经设置了 beanstalkd 并使用了队列。 我还设置了非常简单的命令,允许我使用 artisan 启动脚本。我对 Laravel 很陌生,我正在尝试创建队列来处理我的处理脚本。 处理脚本将由每晚的 cron 作业触发。

我已经设置了 beanstalkd 并使用了队列。 我还设置了非常简单的命令,允许我使用 artisan 启动脚本。

我遇到的主要问题是我的脚本中有依赖项。 例如:

A -> B -> C
       -> D

我需要脚本A首先运行成功,然后B需要成功运行,然后C和D需要运行,但C和D的顺序并不重要

这些都是非常不同的任务,我想将它们分开,但需要管理我队列中的依赖关系。我已经创建了模型和库来处理我的处理,一切都很好。

由于我已经在模型中包含了我的逻辑,我只需要对我的队列进行少量调用。 最初我只想使用闭包并将其全部写入一个文件,下面是一个简单的示例。

Queue::push(function($jobA) use ($id)
{
    ProcessA::doStuff($id);
    $jobA->delete();
});

这行得通,但这仅适用于 A,我仍然需要添加 B、C 和 D。 所以我决定在其中添加一个闭包。

Queue::push(function($jobA) use ($id)
{
    $statusA = ProcessA::doStuff($id);

    if($statusA)
    {
        Queue::push(function($jobB) use ($id)
        {
            ProcessB::doStuff($id);
            $jobB->delete();
        });
    }

    $jobA->delete();
});

这不起作用。 在闭包内运行闭包似乎存在问题。 也可能存在问题,jobA 甚至可能在 jobB 开始之前就被删除。

这个例子比我实际需要做的要简单一些。 这是一个更好的例子……在完成 A 之后,我现在需要获取一系列事物并遍历每个事物并运行 B。然后从前面我说我有 C 和 D,它们是从 B 产生的。 .. 但我什至还没有进入 C 和 D 部分,因为这已经变得很复杂了。

Queue::push(function($jobA) use ($id)
{
    $statusA = ProcessA::doStuff($id);

    if($statusA)
    {
        $things = getThings($id);
        foreach($things as $thing)
        {
            Queue::push(function($jobB) use ($thing)
            {
                ProcessB::doStuff($thing);
                $jobB->delete();
            });
        }
    }

    $jobA->delete();
});

所以嵌套闭包仍然不起作用。 我的下一步是不嵌套闭包,而是编写类。 要开始我必须做的 A 过程

Queue::push('ProcessA', array('id' => $id));

然后

class ProcessA {

    public function fire($job, $data)
    {
        $things = getThings($data['id']);
        foreach($things as $thing)
        {           
            Queue::push('ProcessB', array('thing' => $thing));
        }       

        $job->delete();
    }

}

然后

class ProcessB {

    public function fire($job, $thing)
    {       
        Queue::push('ProcessC', array('id' => $thing['id']));
        Queue::push('ProcessD', array('id' => $thing['id']));
    }       

    $job->delete();

}

ProcessC 和 ProcessD 在这一点上是无关紧要的,只要它们运行。 这种方法似乎有效,但我认为有时当 processA 在 ProcessB 生成之前完全完成时我会遇到问题。弄清楚这些事情是漫长的一天,也许这确实可以正常工作...需要进行更多测试。

由于 Laravel 或 PHP 5.4 中的自动加载魔法,此方法还要求我为正在运行的每个 ProcessA/B/C/D 创建一个单独的文件。正如你所看到的,每一个都很短。这似乎是一种相当复杂的做事方式。

  • 这种方法看起来有什么缺陷吗?
  • 我应该以其他方式执行此操作吗?
  • 我是否应该将其初始化为工匠命令并切换到路由并使用 curl 调用它们?
  • 有没有办法让嵌套闭包起作用?

【问题讨论】:

  • 您可以在您的第一个闭包完成其工作时触发一个事件,然后在其他地方收听该事件。当你抓住它时,将下一个作业推入队列等。
  • 这就是我最终要做的,它只需要我将东西重组到自己的文件中,但这似乎是处理它的正确方法。事情已经运行了一个多月,并且运行良好,谢谢。
  • 酷。我根据我的评论创建了一个答案,因为这就是您现在所做的。如果你能接受就好了:)

标签: command queue laravel laravel-4 beanstalkd


【解决方案1】:

我能想到的最简单的方法:当你的第一个闭包完成它的工作时触发一个事件,然后在其他地方收听该事件。当你抓住它时,将下一个作业推入队列等。

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 2012-03-29
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2015-03-30
    • 2015-02-01
    • 2017-09-30
    相关资源
    最近更新 更多