2016-07-25 26 views
0

我有一個延遲作業的應用程序。我想在操作完成後(回收,成功或結束)使用回調並在客戶端通知用戶。我有這樣的事情:延遲作業後的回調方法 - 呈現js提醒

class ScannerJob < ApplicationJob 
    queue_as :default 

    def perform(links, count = 0) 
    links do |url| 
     broadcast_it(url.to_s, count +=1) 
    end 
    after 
    end 

    def after 
    respond_to do |format| 
     format.js { render :js => "alert('Congratulations');" } 
    end 
    end 

我得到了這樣的事情:未終止的字符串符合結束。我發現這個消息來源說這是不可能的。

什麼是處理這個問題,爲什麼我不能簡單地調用響應JS的最佳方式?

謝謝!

回答

1

是的,這是不可能的。讓我們來找出原因。 我很積極的看你如何正常HTTP請求循環工作。 以傳統方式Client要求Server滿足他的要求。無論是查詢數據還是發送數據以存儲在服務器上。服務器處理客戶端的請求並將響應發送給客戶端。在服務器完全滿足客戶請求之後,除非客戶再次請求/請求,否則服務器不會與客戶進行通信。所以基本上客戶端請求服務器和服務器響應該請求並等待下一個請求。

沒有讓我們去延遲工作的東西。 你知道我們爲什麼在我們的項目中添加延遲的工作。如果我們同步處理它們,可能會出現一些性能不佳或者耗時的任務,這些任務會延遲用戶的響應。 I-E

假設我想在用戶的請求單獨發送電子郵件至100人,每封電子郵件需要5秒以遞送。所以這需要500秒(大約9分鐘)來完成所有這些。

我們不能做一個同步的方式,因爲它會爲用戶帶來一個糟糕的體驗。用戶請求會超時,或者即使不超時,用戶也會將其視爲無響應請求並離開該站點。

所以我們做什麼,我們處理這些電子郵件發送任務作爲背景。每當用戶請求向100人發送電子郵件時,我們立即將響應發回給用戶,並告訴他們成功的消息。並且我們要求延遲的工作在後臺處理這個任務。

class MyController < ApplicationController 
def process_heavy_requestion 
    EmailerSender.delay.send_email_in_backgroun(params) #We are delegating email sending task to delayed job. And we assume it will be done. 
    render text: "Email sent Successfully" 
end 
end 

在此操作中,我們回覆了用戶的消息。並在後臺發送電子郵件。

所以,如果我們把它映射到上面的討論,然後服務器已經成功消息迴應客戶端。 所以,如果我們想發送一個迴應用戶後字,那麼這是不可能的。除非用戶再次要求我們。

所以現在讓我們來解決你的問題。

你想通知使用關於後臺任務的實際進度,那麼這裏是一個方法。 每當任務在後臺執行時,您可以在用戶表/或任何其他表中設置一個標誌。該任務的狀態如何。即使您可以在自定義工作人員中添加另一列。

在調用後臺任務都需要在列的值更改爲「待定」。在延遲在職職工您將設置

所以基本任務輸出將介於存儲在數據庫中,甚至可以將其存儲在用戶會話中列的值相應的i-E(失敗或完成)。

因此,無論何時用戶要求處理該請求,您將在後臺處理taks,並在javascript中添加一個腳本作爲響應,該腳本將在固定時間i-e(5秒)後檢查該任務的結果。所以使用JavaScript,你會在每X秒之後將請求發送到服務器,我以前的任務的狀態如何。如果服務器響應已完成,則向用戶顯示成功消息,或者如果失敗,則向用戶顯示錯誤消息。

我希望它能清除你的困惑

+0

完美!非常感謝。我最終通過使用ActionCable解決了它。我試過後(工作)的方法,但沒有弄清楚它是如何工作的。 – Dudis