2013-05-29 125 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

我可以想出最簡單的方法:只要在第一次關閉完成其工作時觸發事件,然後在其他地方聽該事件。當你抓住它時,將下一個工作推到隊列中等等。