2013-05-29 83 views
3

我是Laravel的新手,并且正在尝试创建队列来处理我的处理脚本。 处理脚本将由夜间cron作业触发。带嵌套闭包,命令和依赖的队列管理器

我有beanstalkd设置和队列已经工作。 我也有非常简单的命令设置,这将允许我使用artisan创建脚本。我对Laravel非常新,并且正在尝试创建队列来处理我的处理脚本。 处理脚本将由夜间cron作业触发。

我有beanstalkd设置和队列已经工作。 我也有非常简单的命令设置,这将允许我使用工匠启动脚本。

我遇到的主要问题是我的脚本中存在依赖关系。 例如:

A -> B -> C 
     -> D 

我需要一个脚本要成功先运行,那么B必须成功运行,那么C和d需要运行,但它并不重要,C和d

顺序

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

因为我已经在模型中有了我的逻辑,所以我只需要一个小小的调用我的队列。 最初我只想使用闭包并将其全部写入一个文件中,下面是一个简单示例。

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

这样的作品,但是这仅仅是一个,我还需要添加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(); 
}); 

这是行不通的。 在闭包内部运行闭包似乎存在问题。 jobB甚至开始之前可能还有jobA可能被删除的问题。

这个例子比我实际需要做的更简单一些。 这是一个更好的例子......在完成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(); 
}); 

因此,嵌套闭包仍然不起作用。 我的下一步是不要嵌套闭包,而是编写类。 要启动一个进程的我会做

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无关,在这一点上,只要它们运行。 这种方法似乎可行,但我认为在processB诞生之前processA会完全完成时,我有时会遇到问题。这是漫长的一天弄清楚这些事情,也许这工作得很好......需要测试更多。

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

  • 此方法在任何方面都有缺陷吗?
  • 我应该以其他方式做这件事吗?
  • 我是否应该将此初始化为artisan命令,然后切换到路由并使用curl调用它们?
  • 有什么办法可以使嵌套关闭工作?
+0

当你的第一个闭包完成它的工作时,你可以触发一个事件,然后在其他地方听这个事件。当你抓住它时,把下一份工作推到队列中等等。 – Franz

+0

这就是我最终做的事情,它只是要求我将结构重组为自己的文件,但似乎是正确的处理方法。事情已经运行了一个多月,并且运行良好,谢谢。 – bsparacino

+0

很酷。我根据我的评论创建了一个答案,因为这就是你现在所做的。会很酷,如果你能接受它:) – Franz

回答

1

我可以想出最简单的方法:只要在第一次关闭完成其工作时触发事件,然后在其他地方听该事件。当你抓住它时,将下一个工作推到队列中等等。