2011-04-06 82 views
1

我目前正在管理在rails 1.2.7上運行的傳統rails應用程序。其中一項功能是允許用戶上傳聲音並使用反引號使用命令行工具進行轉換。目前,我使用AJAX輪詢通過控制器操作來完成轉換管理,但是我遇到了超時問題,這意味着控制器操作的最終元素不會發生。Rails上的異步任務系統?

這是一個需要低開銷的系統,我可以使用什麼來管理這種背景轉換,然後在一個平衡系統中響應由背景轉換創建的問題?我在看eventmachine,但我仍然不是100%,有沒有其他種類的基於異步任務的系統可以使用?

回答

1

首先,哇,Rails 1.2.7。我有一個類似年齡的應用程序在工作,我正在慢慢升級到Rails 3. Crazy這個東西變化的速度有多快。

絕對是一個有趣的問題。有很多方向,你可以採取這一點,我不知道哪個是最好的,因爲我不知道我理解你的過程。所以我會建議一對夫婦。我的理解是1)上傳文件,2)開始轉換,3)通過ajax輪詢報告轉換狀態。如你所發現的,首先,在Rails控制器動作中運行轉換實用程序絕對不是你要走的路。 1)您的Web服務器或瀏覽器可能會終止請求,並且2)大多數Rails部署只允許每個應用程序一次請求一次,這意味着如果您希望同時上傳5個用戶,則需要運行5個應用程序副本。顯然這不會縮放。

您的「上傳」操作應儘可能快。它應該1)上傳文件,2)安排或者啓動一個「轉換作業」,其他進程可以處理。您的投票行動只會報告該職位的狀態。當然,問題是其他過程應該是什麼。

理念1 http://geekblog.vodpod.com/2007/08/17/background-processing-in-rails/可能開始的好地方,雖然我不能保證這種做法。

想法2 我已經做了類似的事情,所以我可以提供更多的細節。它可能更好地擴展。使用Sinatra或Async Sinatra構建輕量級伴侶應用程序。您的Rails應用程序會爲您的數據庫中上載的文件記錄一項作業,但其作業已完成。您的Sinatra應用程序使用EventMachine將每隔幾秒輪詢一次數據庫並開始新的作業。您可能希望將其限制爲n個併發作業,因此您不需要DOS自己的盒子:)然後,您的用戶可以查詢您的Sinatra應用程序以獲取其轉換狀態。

想法3 與2相似,但與其他Web應用程序不同,它只是一個使用EventMachine的小型Ruby程序。你只需在你的服務器上啓動這個程序,並讓它永久運行。每個作業都會將其狀態寫回到數據庫,您的用戶可以通過您的Rails應用程序進行輪詢。我認爲這是我的最愛。線框:

#!/usr/bin/env ruby 
require 'rubygems' 
require 'eventmachine' 

# Returns new jobs from the database 
def new_jobs 
    [] 
end 

# Convert the file 
def convert(job) 
    `convert #{job.path}` 
    job 
end 

# Callback when conversion is complete 
def callback(job) 
    puts "Finished #{job.path}!" 
end 

EventMachine::run do 
    # Run every 5 seconds 
    EventMachine::add_periodic_timer(5) do 
    new_jobs.each { |job| EventMachine::defer convert(job), callback(job) } 
    end 
end 

這些建議是從萬英尺公認的觀點,但我希望有東西在裏面,讓你開始。

+1

我會試圖認真考慮使用DelayedJob或BackgroundJob來支持這種方法。他們會爲你處理所有的工作跟蹤和投票,讓你專注於你的應用代碼。通過Ajax回報狀態可以通過更新正在處理的任何對象的狀態字段來完成。 – 2011-04-06 05:30:14