2016-03-15 12 views
1

我在我的應用程序中實現了API速率限制,用於調用第三方API服務,該服務限制了在指定的時間間隔內對服務進行請求的次數。在正在進行的工作結束之前,單個延遲的工作工人是否可以開始下一個工作?

我經歷了延遲的工作文件,無法找到我正在尋找的信息。

我的情況是;

如果時間很短,比如5秒鐘,在兩個延遲的工作之間,工人會做什麼?

即使第二個作業執行時間已到,它是否會等待第一個作業完成,還是會在指定時間內開始作業?

如果是後者,它會打破我的速率限制實現,因爲API只允許我每分鐘發出60個請求,並且兩個作業都將自己限制爲每分鐘60個請求,總共兩個作業都會嘗試發送大約120個請求在一分鐘內。

在此先感謝,歡呼!

回答

3

這取決於可用的DelayedJob工作人員的數量。因爲免費的工作人員會盡快找到工作並處理它。

如果您需要確保只對工作在同一時間運行,我看到了兩個簡單的選擇:

  1. 限制你的員工的數量1。或
  2. 排列下一個工作作爲處理的最後一步。

這可能是這樣的:

class Job 
    def process 
    # code for the job ... 

    # enqueue the next job to run in 5 seconds 
    Job.delay(run_at: 5.seconds.from_now).process 
    end 
end 

是更復雜一點,有named queues扮演的第三種選擇。當您將這類作業排入特定的命名隊列時,您可以使用該特殊隊列計算下一個作業的時間。而不是僅僅排隊這樣的工作:

Job.delay.process 

檢查作業是否已經存在,就像這樣:

queue_name = 'one_at_a_time' 
latest_job = Delayed::Job.where(queue: queue_name).order(:run_at).last 
run_at  = latest_job ? latest_job.run_at + 5.seconds : Time.current 
Job.delay(queue: queue_name, run_at: run_at).process 
+0

感謝您的快速回復! 我已經將工作人員減少到1人,並且如果我正確地忽略了它,這就足夠了嗎?工作人員將忙於第一份工作,只有在第一份工作完成時纔會開始工作。 「 」將下一份工作列爲處理的最後一步。「你能詳細說明一下嗎?在我的應用程序中,用戶是安排工作的用戶,因此無法知道他們什麼時候計劃他們的工作。 – whizzkid

+1

是的,將工作人員降至1將確保一次只有一個工作正在運行。我不知道用戶在您的應用中安排工作。在這種情況下,第二個版本不起作用。但是,那麼可能有另一種選擇。將在幾分鐘內更新我的答案...... – spickermann

+0

非常感謝詳細的解釋,我看到你在那裏做了第三個選擇,可以工作,但它需要一個不同的實現。因爲上一份工作並不總是能夠與我們即將創造的工作相沖突的人,對嗎?用戶可以安排下個月的工作,也可以安排下一個工作日。例如,我需要檢查他上一個和下一個10秒,以查看是否有任何潛在的衝突。但現在我會和我認爲的單身工人一起去。 – whizzkid

0

而另一種選擇是運行每個隊列一個工人實例:

RAILS_ENV=production bin/delayed_job --queue=tracking start

RAILS_ENV=production bin/delayed_job --queues=mailers,tasks start

Documentation