2011-04-06 46 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