2017-05-05 57 views
3

用戶後創建的新產品,在我的應用程序,然後我做一些操作像更新幾個表:統計,金融,使用,庫存等如何執行任務,避免用戶被迫等待響應?

現在,用戶必須等待,因爲我已經完成了所有步驟。如果很多用戶托盤在同一時間完成,那麼等待的時間就會多得多,這並不是那麼好。

我的計劃是創建一個特殊的TASK_TABLE(產品,時間,TASK_ID),然後在後臺運行此任務,但:

  • 最早的第一,
  • 沒有爲下一個動作停止用戶,
  • 儘快執行此任務。

我該如何在Symfony中做到這一點?

這樣做的最佳方法是什麼?

回答

4

這樣做的最佳方法是什麼?

我不知道這個「是」最好的辦法,但最常見的方式來處理這種類型(根據所提供的 FEWS信息)情況是:

  • 解耦在一個或多個services中「操作」(更新統計數據,財務,使用情況,庫存等),以便能夠在任何地方重複使用 。
  • 打造的「事件」級(末是一個簡單的DTO),你的情況可能是一個NewProductEvent,其中存儲新產品對象:
  • 打造的「監聽」類NewProductListener,其中手柄,該手柄「操作」執行,順序等。

現在用戶必須等待我完成了所有步驟。

爲了避免這種情況,我們必須能夠「發出」我們new_product_created事件後,才響應已提供給客戶端,我們可以做到這一點using a service tag和更具體的kernel terminate event

但是如何存儲產品數據以在kernel.terminate上獲得它?

讓我們去實施它。

「事件」 類:

use Symfony\Component\EventDispatcher\Event; 
use YourApp\YourBundle\Entity\Product; 

class NewProductEvent extends Event 
{ 
    const EVENT_NAME = 'new_product_created'; 

    protected $product; 

    public function __construct(Product $newProduct) 
    { 
     $this->product = $newProduct; 
    } 

    public function getProduct() 
    { 
     return $this->product; 
    } 
} 

的 「監聽」 類:

class NewProductListener 
{ 
    protected $product; 

    public function __construct() 
    { 
     # then you can inject all dependencies needed to perform your tasks 
    } 

    public function onNewProductCreated(Product $newProduct) 
    { 
     # here you keep in memory the product data! 
     $this->product = $newProduct->getProduct(); 
    } 

    public function performTasks() 
    { 
     if ($this->product) { 
      # here you can put the logic to perform all needed tasks! 
     } 
    } 
} 

監聽器 「服務」 的定義:

<service id="new_product_listener" 
     class="YourApp\YourBundle\Event\NewProductListener"> 
    <!-- you can inject in the listener, as argument, each service task you need --> 
    <!-- <argument type="service" id="financial_operation_service"/>--> 
    <!-- <argument type="service" id="usage_operation_service"/>--> 
    <tag name="kernel.event_listener" event="new_product_created" method="onNewProductCreated"/> 
    <tag name="kernel.event_listener" event="kernel.terminate" method="performTasks"/> 
</service> 

現在的實際例子(我不評論代碼,因爲它是不言自明的):

// presuming you are in a controller: 
$dispatcher = $this->get('event_dispatcher'); 
$newProduct = //--- I don't know from where it will come. 
$event  = new NewProductEvent($newProduct); 
$dispatcher->dispatch(NewProductEvent::EVENT_NAME, $event); 

當你發送的NewProductEvent :: EVENT_NAME(new_product_created),你將存儲產品數據觸發onNewProductCreated方法在NewProductListener聽衆的$product變量,然後能夠在kernel.terminate事件被觸發後,使用它!

通過這種方式,Symfony將執行所需的任務(在背景)並且不會降低用戶體驗。

一些參考:

+0

感謝@gp_sflover的全面解釋。 – janek1